diff --git a/.codeclimate.yml b/.codeclimate.yml index 3760d0042..2bc90b200 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -1,7 +1,9 @@ version: "2" prepare: fetch: - - "https://raw.githubusercontent.com/internetee/style-guide/master/ruby/.rubocop.yml" + - "https://raw.githubusercontent.com/internetee/style-guide/master/.rubocop-ruby.yml" + - url: "https://raw.githubusercontent.com/internetee/style-guide/master/.rubocop-rails.yml" + path: ".rubocop.yml" plugins: brakeman: enabled: true @@ -20,27 +22,25 @@ plugins: enabled: true rubocop: enabled: true - channel: rubocop-0-58 + channel: rubocop-0-74 +checks: + method-lines: + config: + threshold: 40 exclude_patterns: - - "app/models/legacy/" - "app/models/version/" - "bin/" - "config/" - "db/" - - "lib/action_controller/" - - "lib/core_ext/" + - "lib/core_monkey_patches/" - "lib/daemons/" - - "lib/gem_ext/" + - "lib/gem_monkey_patches/" - "lib/tasks/api_log.rake" - "lib/tasks/bootstrap.rake" - - "lib/tasks/convert.rake" - "lib/tasks/db.rake" - "lib/tasks/documents.rake" - - "lib/tasks/import.rake" - "lib/tasks/legal_doc.rake" - - "lib/tasks/statuses.rake" - "lib/tasks/whois.rake" - - "spec/" - "test/" - "vendor/" - "CHANGELOG.md" diff --git a/.editorconfig b/.editorconfig index 5f4df341d..95ad0d2d5 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,7 +7,7 @@ indent_style = space indent_size = 2 max_line_length = 100 trim_trailing_whitespace = true -insert_final_newline = false +insert_final_newline = true -[*.{html,erb}] +[*.{html,erb,js}] indent_size = 4 \ No newline at end of file diff --git a/.ruby-gemset b/.ruby-gemset index 14bc599bf..4dcdb08b2 100644 --- a/.ruby-gemset +++ b/.ruby-gemset @@ -1 +1 @@ -registry +-global \ No newline at end of file diff --git a/.ruby-version b/.ruby-version index 59aa62c1f..57cf282eb 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.4.5 +2.6.5 diff --git a/.simplecov b/.simplecov deleted file mode 100644 index 737a1945c..000000000 --- a/.simplecov +++ /dev/null @@ -1,8 +0,0 @@ -SimpleCov.start 'rails' do - add_filter '/app/models/legacy/' - add_filter '/app/models/version/' - add_filter '/lib/action_controller/' - add_filter '/lib/core_ext/' - add_filter '/lib/daemons/' - add_filter '/lib/gem_ext/' -end \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 053699a2e..23d4ab6b1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,6 @@ language: ruby cache: bundler env: - DB=postgresql -bundler_args: --without development staging production before_install: - "wget -N http://chromedriver.storage.googleapis.com/2.43/chromedriver_linux64.zip -P ~/" - "unzip ~/chromedriver_linux64.zip -d ~/" @@ -10,20 +9,25 @@ before_install: - "sudo mv -f ~/chromedriver /usr/local/share/" - "sudo chmod +x /usr/local/share/chromedriver" - "sudo ln -s /usr/local/share/chromedriver /usr/local/bin/chromedriver" - - "gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true" - - "gem install bundler -v '< 2'" + - "bundle config set without 'development staging production'" + - "bundle config set deployment '[secure]'" before_script: - - "cp config/application-example.yml config/application.yml" - - "cp config/database-travis.yml config/database.yml" + - "cp config/application.yml.sample config/application.yml" + - "echo \"openssl_config_path: 'test/fixtures/files/test_ca/openssl.cnf'\" >> config/application.yml" + - "echo \"crl_dir: 'test/fixtures/files/test_ca/crl'\" >> config/application.yml" + - "echo \"crl_path: 'test/fixtures/files/test_ca/crl/crl.pem'\" >> config/application.yml" + - "echo \"ca_cert_path: 'test/fixtures/files/test_ca/certs/ca.crt.pem'\" >> config/application.yml" + - "echo \"ca_key_path: 'test/fixtures/files/test_ca/private/ca.key.pem'\" >> config/application.yml" + - "echo \"ca_key_password: 'password'\" >> config/application.yml" + - "cp config/database_travis.yml config/database.yml" - "bundle exec rake db:setup:all" - "curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter" - "chmod +x ./cc-test-reporter" - "./cc-test-reporter before-build" -script: - - "bundle exec rspec" - - "bundle exec rake test" after_script: - "./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT" +script: + - "bundle exec rails test test/*" services: - postgresql addons: diff --git a/CHANGELOG.md b/CHANGELOG.md index 2811370e8..b2e5749c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,397 @@ +01.09.2020 +* Removed some unused settings from admin [#1668](https://github.com/internetee/registry/issues/1668) + +27.08.2020 +* Fixed internal error in domain history [#1663](https://github.com/internetee/registry/issues/1663) +* Second lvl zone records return now empty string for dnskey values [#1665](https://github.com/internetee/registry/issues/1665) + +26.08.2020 +* Fixed website url display issue in PDF invoices [#1188](https://github.com/internetee/registry/issues/1188) +* Added error logging for missing cert_path [#1420](https://github.com/internetee/registry/pull/1420) +* Refactored settings store mechanism [#1629](https://github.com/internetee/registry/issues/1629) +* Registrant API now returns users' business contacts [#1642](https://github.com/internetee/registry/issues/1642) + +14.08.2020 +* Added handling of second lvl zoness managed by the registry in whois records [#1661](https://github.com/internetee/registry/issues/1661) + +13.08.2020 +* Removed keystore gem and replaced LHV JKS with PKCS12 [#1645](https://github.com/internetee/registry/issues/1645) + +11.08.2020 +* Fixed postal address saving bug with disabled address processing [#1650](https://github.com/internetee/registry/issues/1650) + +07.08.2020 +* Restored creator and updator strings to contacts and related object records [#1636](https://github.com/internetee/registry/issues/1636) +* Security gem updates: sdoc to 1.1 and json to 2.3.1 [#1657](https://github.com/internetee/registry/pull/1657) + +04.08.2020 +* Fixed registrant verification for domain delete [#1631](https://github.com/internetee/registry/issues/1631) +* Fixed domain transfer issue when one person was present in the same role more than once (different objects) [#1651](https://github.com/internetee/registry/issues/1651) + +03.08.2020 +* Fixed 0 vat issue with invoices sent to Directo [#1647](https://github.com/internetee/registry/issues/1647) + +17.07.2020 +* Added turemail gem for validating email addresses syntactically and on MX record level [#297](https://github.com/internetee/registry/issues/297) + +15.07.2020 +* Reapplied race condition fix after fixing the data in prod env [#1612](https://github.com/internetee/registry/issues/1612) + +07.07.2020 +* Fixed legaldoc validation [#1634](https://github.com/internetee/registry/issues/1634) +* Disabled collection cashe versioning [#1637](https://github.com/internetee/registry/pull/1637) + +03.07.2020 +* 1-character domains are now valid but blocked by default [#1625](https://github.com/internetee/registry/issues/1625) + +02.07.2020 +* Adding legaldoc to domain:delete is now optional [#1624](https://github.com/internetee/registry/issues/1624) +* Setting to make legaldoc functionality optional [#1623](https://github.com/internetee/registry/issues/1623) + +01.07.2020 +* Reverted race condition fix due to data issues in production (#1612) [#1622](https://github.com/internetee/registry/pull/1622) +* Added legaldoc opt-out option for approved registrars [#1620](https://github.com/internetee/registry/issues/1620) + +29.06.2020 +* Bumped rack to 2.2.3 [#1618](https://github.com/internetee/registry/pull/1618) +* Actionpack security update to 6.0.3.2 [#1619](https://github.com/internetee/registry/pull/1619) + +26.06.2020 +* Fixed race condition in domain update by adding new db constratints [#1612](https://github.com/internetee/registry/issues/1612) +* Refactored contact validation [#1617](https://github.com/internetee/registry/pull/1617) + +19.06.2020 +* Regsitrant API returns now DNSSEC info [#1613](https://github.com/internetee/registry/pull/1613) +* Updated domain expiration email notification texts [#1614](https://github.com/internetee/registry/pull/1614) + +15.06.2020 +* Added contact email to registrant API [#1611](https://github.com/internetee/registry/pull/1611) + +12.06.2020 +* Extracted Xml deserializing from EPP Contact and Domain classes [#1601](https://github.com/internetee/registry/pull/1601) +* Fixed whois data update issue with child object updates [#1604](https://github.com/internetee/registry/issues/1604) + +11.06.2020 +* Auction API returns json on error [#1605](https://github.com/internetee/registry/issues/1605) +* Fixed account activity index in admin [#1606](https://github.com/internetee/registry/issues/1606) + +08.06.2020 +* Bumped websocket-extensions to 0.1.5 [#1602](https://github.com/internetee/registry/pull/1602) + +04.06.2020 +* Moved dev config to sample file [#1599](https://github.com/internetee/registry/pull/1599) +* Post Rails6 upgrade fixes [#1598](https://github.com/internetee/registry/pull/1598) + +03.06.2020 +* Upgraded Rails to 6.0.3 [#1593](https://github.com/internetee/registry/pull/1593) + +02.06.2020 +* Fixed registration deadline format for whois/restwhois [#1595](https://github.com/internetee/registry/pull/1595) + +01.06.2020 +* Improved error handling in case legal doc is not found for downloading [#1452](https://github.com/internetee/registry/issues/1452) + +29.05.2020 +* Bump kaminari to 1.2.1 [#1592](https://github.com/internetee/registry/pull/1592) + +28.05.2020 +* REPP returns list of disputed domains [#1588](https://github.com/internetee/registry/issues/1588) +* Updated Directo gem [#1590](https://github.com/internetee/registry/pull/1590) +* Updated LHV gem [#1591](https://github.com/internetee/registry/pull/1591) + +25.05.2020 +* Fixed registrant change verification bug for disputed domains [#1586](https://github.com/internetee/registry/issues/1586) + +22.05.2020 +* New solution for managing domains with effective dispute commitee decision [#269](https://github.com/internetee/registry/issues/269) +* Bump puma from 4.3.5 [#1585](https://github.com/internetee/registry/pull/1585) +* Run all CI tests [#1584](https://github.com/internetee/registry/pull/1584) + +21.05.2020 +* Fixed contact view access bug in registrant [#1527](https://github.com/internetee/registry/pull/1527) +* REPP returns list of domains currently at auction [#1582](https://github.com/internetee/registry/pull/1582) + +18.05.2020 +* REPP returns list of reserved and blocked domains [#1569](https://github.com/internetee/registry/issues/1569) + +14.05.2020 +* Deleted certificates are now revoked first [#952](https://github.com/internetee/registry/issues/952) + +11.05.2020 +* Auction process due dates are now available over whois and rest-whois [#1201](https://github.com/internetee/registry/issues/1201) + +30.04.2020 +* Fix for internal error on opening domain history with legacy id record [#1576](https://github.com/internetee/registry/issues/1576) + +27.04.2020 +* Downgrade SimpleCov to 0.17 due to incompatibiilty with CodeClimate [#1575](https://github.com/internetee/registry/pull/1575) + +17.04.2020 +* Webinterfaces have now clickable version string pointing to the latest deployed commit in github [#1345](https://github.com/internetee/registry/pull/1345) + +15.04.2020 +* Updated Rails to 5.2 and fixed acitionview security issue [#1568](https://github.com/internetee/registry/issues/1568) + +25.03.2020 +* Implemented Directo gem [#1547](https://github.com/internetee/registry/pull/1547) + +11.03.2020 +* Fixed glue record issues when using 2nd level domain as host [#1562](https://github.com/internetee/registry/issues/1562) + +10.03.2020 +* Updated lhv, e-invoice & company_register gem due to security updates [#1564](https://github.com/internetee/registry/pull/1564) + +06.03.2020 +* Record payment method and failed payments [#1422](https://github.com/internetee/registry/issues/1422) + +04.03.2020 +* Bump Puma to 4.3.3 [#1557](https://github.com/internetee/registry/pull/1557) + +03.03.2020 +* Admin: fixed import of th6 bank statement [#1551](https://github.com/internetee/registry/issues/1551) + +02.03.2020 +* Registrar: fixed statuses based contact filtering [#1004](https://github.com/internetee/registry/issues/1004) + +28.02.2020 +* Registrar: fixed account switching [#1535](https://github.com/internetee/registry/issues/1535) + +27.02.2020 +* Registrar: fixed the verified checkbox bug that did not change the element value to yes in epp request [#1540](https://github.com/internetee/registry/issues/1540) +* Ruby version update to 2.6.5 [#1545](https://github.com/internetee/registry/pull/1545) + +26.02.2020 +* Registrar: added an option to remove clientHold status [#1481](https://github.com/internetee/registry/issues/1481) +* Admin: fixed domain status removal issue [#1543](https://github.com/internetee/registry/issues/1543) +* Implemented consistent and automated data migrations [#1298](https://github.com/internetee/registry/issues/1298) + +20.02.2020 +* E-invoice sending to Que to manage resending in case of an error [#1509](https://github.com/internetee/registry/issues/1509) +* Check to make sure all monthly invoices fit in available invoice number range [#277](https://github.com/internetee/registry/issues/277) +* Disabled aurbreak performance monitoring [#1534](https://github.com/internetee/registry/pull/1534) + +14.02.2020 +* Fixed Papertrail warnings [#1530](https://github.com/internetee/registry/issues/1530) + +12.02.2020 +* Fixed papertrails double recording issue [#1526](https://github.com/internetee/registry/issues/1526) +* Requests to Directo are now saved for both credit and monthly invoices [#344](https://github.com/internetee/registry/issues/344) + +10.02.2020 +* Resolved Money gem deprecation warning and silenced all warnings due plan to replace papertrail [#1522](https://github.com/internetee/registry/pull/1522) + +06.02.2020 +* Permit & turn ActiveController::Parameters to hash on domain create [#1516](https://github.com/internetee/registry/issues/1516) + +05.02.2020 +* Ruby version upgrade to 2.6.3 [#846](https://github.com/internetee/registry/issues/846) +* Added retries & raise to connect api to handle timeouts [#1474](https://github.com/internetee/registry/issues/1474) +* Added logging of XML if there is NoMethodError#text on xml data fields [#1475](https://github.com/internetee/registry/issues/1475) + +04.02.2020 +* Fixed bug that allowed bypassing blocked domain validation using punycode [#1142](https://github.com/internetee/registry/issues/1142) +* SimpleIDN gem update to 0.0.9 [#1508](https://github.com/internetee/registry/pull/1508) + +31.01.2020 +* Instant payments marks specific invoice as paid [#1500](https://github.com/internetee/registry/issues/1500) +* Sending invoice payment date to accounting [#1416](https://github.com/internetee/registry/issues/1416) + +29.01.2020 +* Fixed the invoice binding bug where process failed if registrar tried to load a sum that they have used before [#1496](https://github.com/internetee/registry/issues/1496) + +28.01.2020 +* Registrar: fixed sorting of domain view [#1461](https://github.com/internetee/registry/issues/1461) +* clientHold status is now set once instead of resetting it every time the job is run [#1480](https://github.com/internetee/registry/issues/1480) + +27.01.2020 +* Admin: fixed history view for domains with legacy id [#1489](https://github.com/internetee/registry/issues/1489) + +23.01.2020 +* Payment invoice matching by looking for ref nr in description field [#1415](https://github.com/internetee/registry/issues/1415) + +22.01.2020 +* ForceDelete poll messages with outzone and purge dates [#1478](https://github.com/internetee/registry/issues/1478) + +21.01.2020 +* Registrant change cancels automatically force delete process [#1479](https://github.com/internetee/registry/issues/1479) + +20.01.2020 +* ForceDelete email notifications are sent to all contacts + info and domain@domain [#1477](https://github.com/internetee/registry/issues/1477) + +18.01.2020 +* New ForceDelete procedure [#1428](https://github.com/internetee/registry/issues/1428) + +16.01.2020 +* Added tests for registrant verification [#1430](https://github.com/internetee/registry/pull/1430) + +14.01.2020 +* removed authinfo element from contact:info response for non-sponsoring registrars [#1446](https://github.com/internetee/registry/issues/1446) + +13.01.2020 +* resolved internal error on registrant confirmation [#1468](https://github.com/internetee/registry/issues/1468) + +10.01.2020 +* updated ForceDelete email templates according new regulation [#1466](https://github.com/internetee/registry/issues/1466) +* regenerated WHOIS db schema [#1436](https://github.com/internetee/registry/pull/1436) + +09.01.2020 +* serverForceDelete status does not block removing clientHold status [#1462](https://github.com/internetee/registry/pull/1462) + +06.01.2020 +* Updated e-invoice gem [#1456](https://github.com/internetee/registry/pull/1456) +* Bumped rack gem to 2.0.8 [#1448](https://github.com/internetee/registry/pull/1448) + +03.01.2020 +* Added an option for registrars to add and remove clientHold status on domains [#1454](https://github.com/internetee/registry/pull/1454) +* Fixed contact view internal error in admin [#1458](https://github.com/internetee/registry/issues/1458) + +27.12.2019 +* Records in registrant_verifications are now archived by PaperTrail [#1425](https://github.com/internetee/registry/issues/1425) + +16.12.2019 +* Bump puma from 4.2.1 to 4.3.1 [#1437](https://github.com/internetee/registry/pull/1437) +* Refactored API user management [#1435](https://github.com/internetee/registry/pull/1435) +* Ignoring legacy database columns at ActiveRecord level [#1377](https://github.com/internetee/registry/issues/1377) +* Removed Ruby version from Travis config and let it use .ruby-version [#1441](https://github.com/internetee/registry/pull/1441) +* Removed `fill_ident_country` postgresql function as unused [#1439](https://github.com/internetee/registry/pull/1439) + +12.12.2019 +* Updated e-invoice gem [#1429](https://github.com/internetee/registry/pull/1429) +* Upgraded bundler to 2.0.2 [#1433](https://github.com/internetee/registry/pull/1433) +* Set not null constraint on contact.name db column [#1417](https://github.com/internetee/registry/pull/1417) +* Removed domain name from registrant_verifications table [#1431](https://github.com/internetee/registry/pull/1431) + +19.11.2019 +* Updated Rails to 5.0.7 [#377](https://github.com/internetee/registry/issues/377) + +15.11.2019 +* Restored EPP exception logging to syslog [#1371](https://github.com/internetee/registry/issues/1371) + +11.11.2019 +* Removed code for displaying errors in nameserver and dnskey data as unused [#1411](https://github.com/internetee/registry/pull/1411) + +07.11.2019 +* Fixed domain details view in admin where admin and tech contacts were marked as invalid with Rails 5 [#1413](https://github.com/internetee/registry/pull/1413) + +06.11.2019 +* Fixed account activity form filter and csv download issues in admin and registrar [#1410](https://github.com/internetee/registry/pull/1410) + +05.11.2019 +* Moved gem extensions to proper directory and renamed the dirs to "moneky patces" to improve readability [#1406](https://github.com/internetee/registry/pull/1406) + +04.11.2019 +* Tuned kaminari gem to solve pagination issues [#1405](https://github.com/internetee/registry/pull/1405) + +01.11.2019 +* Typo fixes for #1352 [#1396](https://github.com/internetee/registry/pull/1396) +* Updated que gem to 0.14.3 and que-web gem to 0.7.2 [#1404](https://github.com/internetee/registry/pull/1404) + +31.10.2019 +* Updated domain_name gem to 0.5.20190701 [#1400](https://github.com/internetee/registry/pull/1400) +* Updated webmock gem to 3.7.6 [#1401](https://github.com/internetee/registry/pull/1401) +* Improved setup and seed [#1352](https://github.com/internetee/registry/pull/1352) +* Removed unimplemented keyrelay code [#715](https://github.com/internetee/registry/issues/715) +* Removed uuidtools gem [#1390](https://github.com/internetee/registry/pull/1390) +* Removed some unneeded code [#1397](https://github.com/internetee/registry/pull/1397) +* Removed eis_trusted_proxies setting [#1398](https://github.com/internetee/registry/pull/1398) + +28.10.2019 +* Updated kaminari gem to 1.1.1 [#1392](https://github.com/internetee/registry/pull/1392) +* Downgraded minitest to 5.10.3 due to incompatibility with Rails 5.0 [#1387](https://github.com/internetee/registry/pull/1387) +* New db constaints to invoices and invoice_items tables [#1388](https://github.com/internetee/registry/pull/1388) +* Removed buggy code for contact details' fast access in regitrar portal [#1386](https://github.com/internetee/registry/pull/1386) + +23.10.2019 +* Updated haml gem to 5.1.2 (CVE-2017-1002201) [#1384](https://github.com/internetee/registry/pull/1384) +* Removed bullet gem [#378](https://github.com/internetee/registry/issues/378) +* Removed duplicate route from admin [#1375](https://github.com/internetee/registry/pull/1375) + +21.10.2019 +* Tuned PDFkit gem [#1367](https://github.com/internetee/registry/pull/1367) +* Removed some dead code [#1370](https://github.com/internetee/registry/pull/1370) + +17.10.2019 +* Implemented properl handling of contact transfer requests [#1363](https://github.com/internetee/registry/pull/1363) +* Test environment tuning [#1366](https://github.com/internetee/registry/pull/1366) + +16.10.2019 +* Contact and domain list download in portals changed - buttons in stead of dropdown [#1360](https://github.com/internetee/registry/pull/1360) +* limited epp routes [#1364](https://github.com/internetee/registry/pull/1364) + +11.10.2019 +* Fixed mailer previews for couple email templates [#1342](https://github.com/internetee/registry/pull/1342) +* Updated ransack gem to 1.8 [#1357](https://github.com/internetee/registry/pull/1357) +* Removed old import rake task [#1355](https://github.com/internetee/registry/pull/1355) + +10.10.2019 +* Added DB constraints for reserved and blocked tables [#1338](https://github.com/internetee/registry/pull/1338) + +08.10.2019 +* Removed unused epp routes [#1335](https://github.com/internetee/registry/pull/1335) +* Removed Rspec and coverted specs to tests [#1336](https://github.com/internetee/registry/pull/1336) +* Added test for EPP hello request [#1337](https://github.com/internetee/registry/pull/1337) +* Removed unused csr and crt columns from user table [#264](https://github.com/internetee/registry/issues/264) +* Bump rubyzip from 1.2.2 to 1.3.0 [#1349](https://github.com/internetee/registry/pull/1349) + +07.10.2019 +* Clarified reference to proper phone nr format in EPP spec [#1343](https://github.com/internetee/registry/pull/1343) + +20.09.2019 +* Fixed error on domain transfer with invalid code [#686](https://github.com/internetee/registry/issues/686) +* EPP exceptions are now sent to Errbit [#539](https://github.com/internetee/registry/issues/539) +* Updated jquery-rails gem to 4.3.5 [#1322](https://github.com/internetee/registry/pull/1322) +* Added EPP renew tests [#1326](https://github.com/internetee/registry/pull/1326) + +17.09.2019 +* Fixed error messages on deletind deletecandidate domains [#718](https://github.com/internetee/registry/issues/718) +* Removed html2haml gem [#1316](https://github.com/internetee/registry/pull/1316) + +16.09.2019 +* Updated coffee-rails gem to 4.2 [#1320](https://github.com/internetee/registry/pull/1320) +* Updated data_migrate gem to 5.3.2 [#1321](https://github.com/internetee/registry/pull/1321) +* Replaced unused haml-rails gem with haml [#1315](https://github.com/internetee/registry/pull/1315) +* Hid some methods [#1318](https://github.com/internetee/registry/pull/1318) + +13.09.2019 +* Fixed bug where glue records were identified on partial string match with the domain name [#1291](https://github.com/internetee/registry/issues/1291) +* Removed 1 second delay on erroneous epp query responses [#1299](https://github.com/internetee/registry/pull/1299) +* Autoupdated Devise gem to 4.7.1 [#1304](https://github.com/internetee/registry/pull/1304) +* Updated Airbrake gem to 9.4.3 and tuned the configuration [#1297](https://github.com/internetee/registry/pull/1297) +* Updated cancancan gem to 3.0.1 [#1300](https://github.com/internetee/registry/pull/1300) +* Updated filenames to follow Ruby name convention [#1295](https://github.com/internetee/registry/pull/1295) +* Removed unused jbuilder gem [#1311](https://github.com/internetee/registry/pull/1311) +* Removed mod_epp specific X-EPP-Returncode EPP response header [#1301](https://github.com/internetee/registry/pull/1301) +* Removed a dublicate test [#1302](https://github.com/internetee/registry/pull/1302) +* Removed disabled and unnecessary CSRF protection [#1305](https://github.com/internetee/registry/pull/1305) +* Introduced modules [#1312](https://github.com/internetee/registry/pull/1312) + +09.09.2019 +* Upgrade Ruby to 2.4.7 [#1289](https://github.com/internetee/registry/pull/1289) + +05.09.2019 +* Update hashdiff gem to 1.0.0 [#1287](https://github.com/internetee/registry/pull/1287) + +03.09.2019 +* Updated Ruby to version 2.5.5 [#1273](https://github.com/internetee/registry/pull/1273) +* Figaro cleanup [#1272](https://github.com/internetee/registry/pull/1272) +* Removed deprecated testcase class [#1277](https://github.com/internetee/registry/pull/1277) + +27.08.2019 +* Added some new database constraints [#1265](https://github.com/internetee/registry/pull/1265) + +26.08.2019 +* Introduced automatic payment processing using LHV Connect [#1232](https://github.com/internetee/registry/issues/1232) +* removed unused script [#1261](https://github.com/internetee/registry/pull/1261) +* removed unused factory [#1262](https://github.com/internetee/registry/pull/1262) +* removed unused seller_it column from invoices db table [#1264](https://github.com/internetee/registry/pull/1264) +* removed unused rake tasks [#1268](https://github.com/internetee/registry/pull/1268) + +21.08.2019 +* Nokogiri update to 1.10.4 (CVE-2019-5477) [#1266](https://github.com/internetee/registry/pull/1266) + +08.07.2019 +* Invoices are not delivered to e-invoice provider when registrar has no billing email [#1255](https://github.com/internetee/registry/issues/1255) + 28.06.2019 * E-invoicing with every generated invoice [#1222](https://github.com/internetee/registry/issues/1222) diff --git a/Dockerfile b/Dockerfile index b5871bfed..5d241eeef 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,4 @@ -FROM internetee/ruby:2.4 -MAINTAINER maciej.szlosarczyk@internet.ee +FROM internetee/ruby:2.6-buster RUN mkdir -p /opt/webapps/app/tmp/pids WORKDIR /opt/webapps/app diff --git a/Gemfile b/Gemfile index fb61fd2ba..12b826e3c 100644 --- a/Gemfile +++ b/Gemfile @@ -1,15 +1,9 @@ -# Use https only for accessing github -# https://github.com/bundler/bundler/pull/3447 -git_source(:github) do |repo_name| - repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/") - "https://github.com/#{repo_name}.git" -end if Bundler::VERSION < '2' - source 'https://rubygems.org' # core -gem 'iso8601', '0.8.6' # for dates and times -gem 'rails', '4.2.11.1' # when update, all initializers eis_custom files needs check/update +gem 'bootsnap', '>= 1.1.0', require: false +gem 'iso8601', '0.12.1' # for dates and times +gem 'rails', '~> 6.0' gem 'rest-client' gem 'uglifier' @@ -17,50 +11,37 @@ gem 'uglifier' gem 'figaro', '1.1.1' # model related -gem 'pg', '0.19.0' -gem 'ransack', '1.5.1' # for searching +gem 'activerecord-import' +gem 'paper_trail', '~> 10.3' +gem 'pg', '1.2.2' +# 1.8 is for Rails < 5.0 +gem 'ransack', '~> 2.3' +gem 'truemail', '~> 1.7' # validates email by regexp, mail server existence and address existence gem 'validates_email_format_of', '1.6.3' # validates email against RFC 2822 and RFC 3696 -gem 'paper_trail', '~> 4.0' # 0.7.3 is the latest for Rails 4.2, however, it is absent on Rubygems server # https://github.com/huacnlee/rails-settings-cached/issues/165 -gem 'rails-settings-cached', '0.7.2' - -# html-xml -gem 'haml-rails', '0.9.0' # haml for views gem 'nokogiri' # style gem 'bootstrap-sass', '~> 3.4' -gem 'sass-rails', '5.0.6' # sass style - -# js - -gem 'coffee-rails', '4.1.0' # coffeescript support -gem 'jquery-rails', '4.0.4' # jquery +gem 'coffee-rails', '>= 5.0' +gem 'jquery-rails' gem 'selectize-rails', '0.12.1' # include selectize.js for select - -# view helpers -gem 'kaminari', '0.16.3' # pagination +gem 'kaminari' gem 'coderay', '1.1.0' # xml console visualize +gem 'sass-rails' gem 'select2-rails', '3.5.9.3' # for autocomplete - -# rights -gem 'cancancan', '1.11.0' # autharization -gem 'devise', '~> 4.0' +gem 'cancancan' +gem 'devise', '~> 4.7' gem 'grape' -gem 'jbuilder', '2.2.16' # json api # registry specfic +gem 'data_migrate', '~> 6.1' gem 'isikukood' # for EE-id validation -gem 'simpleidn', '0.0.7' # For punycode +gem 'simpleidn', '0.1.1' # For punycode gem 'money-rails' - -# deploy -gem 'data_migrate', - github: 'internetee/data-migrate', - ref: '35d22b09ff37a4e9d61ab326ad5d8eb0edf1fc81' gem 'whenever', '0.9.4', require: false # country listing @@ -73,50 +54,43 @@ gem 'digidoc_client', ref: '1645e83a5a548addce383f75703b0275c5310c32' -gem 'epp', '1.5.0', github: 'internetee/epp' +gem 'epp', github: 'internetee/epp', branch: :master gem 'epp-xml', '1.1.0', github: 'internetee/epp-xml' -gem 'uuidtools', '2.1.5' # For unique IDs (used by the epp gem) - -# que -gem 'que', '0.10.0' +gem 'que' gem 'daemons-rails', '1.2.1' -gem 'que-web', '0.4.0' - -# for importing legacy db -gem 'activerecord-import', '0.7.0' # for inserting dummy data - +gem 'que-web' gem 'pdfkit' gem 'jquery-ui-rails', '5.0.5' -gem 'active_model-errors_details' # Backport from Rails 5, https://github.com/rails/rails/pull/18322 gem 'airbrake' gem 'company_register', github: 'internetee/company_register', branch: :master gem 'e_invoice', github: 'internetee/e_invoice', branch: :master +gem 'lhv', github: 'internetee/lhv', branch: 'master' +gem 'domain_name' +gem 'haml', '~> 5.0' +gem 'wkhtmltopdf-binary', '~> 0.12.5.1' + +gem 'directo', github: 'internetee/directo', branch: 'master' group :development do # deploy + gem 'listen', '3.2.1' gem 'mina', '0.3.1' # for fast deployment end group :development, :test do - gem 'factory_bot_rails' - gem 'capybara' - gem 'rspec-rails', '~> 3.6' - gem 'selenium-webdriver' - - # debug gem 'pry', '0.10.1' - - gem 'bullet', '4.14.7' # for finding database optimizations - gem 'html2haml', '2.1.0' - gem 'sdoc', '0.4.1' # bundle exec rake doc:rails generates the API under doc/api. gem 'railroady', '1.3.0' # to generate database diagrams gem 'autodoc' gem 'puma' + gem 'sdoc', '~> 1.1' end group :test do + gem 'capybara' gem 'database_cleaner' - gem 'simplecov', require: false + gem 'minitest', '~> 5.14' + gem 'simplecov', '0.17.1', require: false # CC last supported v0.17 + gem 'webdrivers' gem 'webmock' end diff --git a/Gemfile.lock b/Gemfile.lock index d71c55eee..f7eb6cf2a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/internetee/company_register.git - revision: da7130542304fc543c90d54cd037d019a777c526 + revision: 86d691997aa7def9f86d88f6c92cabb86cd65487 branch: master specs: company_register (0.1.0) @@ -8,16 +8,17 @@ GIT savon GIT - remote: https://github.com/internetee/data-migrate.git - revision: 35d22b09ff37a4e9d61ab326ad5d8eb0edf1fc81 - ref: 35d22b09ff37a4e9d61ab326ad5d8eb0edf1fc81 + remote: https://github.com/internetee/directo.git + revision: 8ff8a382d004ffb85722a6a7a68a020bd4d7159b + branch: master specs: - data_migrate (1.3.0) - rails (>= 4.1.0) + directo (1.0.1) + money (~> 6.13) + nokogiri (~> 1.10) GIT remote: https://github.com/internetee/e_invoice.git - revision: 917318bd546322408b83567745375c998619c926 + revision: b374ffd7be77b559b30c7a0210dc0df5ac3ed723 branch: master specs: e_invoice (0.1.0) @@ -27,20 +28,30 @@ GIT GIT remote: https://github.com/internetee/epp-xml.git - revision: 5dd542e67ef26d58365f30e553254d6db809277d + revision: 27959f8cb244ea5eabaeeee747984988b454e840 specs: epp-xml (1.1.0) - activesupport (~> 4.1) + activesupport (>= 4.1) builder (~> 3.2) GIT remote: https://github.com/internetee/epp.git - revision: 1a50f2144f15a2d975337e56fb1ccaba5d956e9d + revision: af7cefda37ac81d14b1d12641cde410776082d59 + branch: master specs: epp (1.5.0) hpricot libxml-ruby +GIT + remote: https://github.com/internetee/lhv.git + revision: 1825240b3bf8b262418cc6c8ef7ed1aba386dd7d + branch: master + specs: + lhv (0.1.0) + logger + nokogiri + GIT remote: https://github.com/tarmotalu/digidoc_client.git revision: 1645e83a5a548addce383f75703b0275c5310c32 @@ -56,74 +67,87 @@ GIT GEM remote: https://rubygems.org/ specs: - actionmailer (4.2.11.1) - actionpack (= 4.2.11.1) - actionview (= 4.2.11.1) - activejob (= 4.2.11.1) + actioncable (6.0.3.2) + actionpack (= 6.0.3.2) + nio4r (~> 2.0) + websocket-driver (>= 0.6.1) + actionmailbox (6.0.3.2) + actionpack (= 6.0.3.2) + activejob (= 6.0.3.2) + activerecord (= 6.0.3.2) + activestorage (= 6.0.3.2) + activesupport (= 6.0.3.2) + mail (>= 2.7.1) + actionmailer (6.0.3.2) + actionpack (= 6.0.3.2) + actionview (= 6.0.3.2) + activejob (= 6.0.3.2) mail (~> 2.5, >= 2.5.4) - rails-dom-testing (~> 1.0, >= 1.0.5) - actionpack (4.2.11.1) - actionview (= 4.2.11.1) - activesupport (= 4.2.11.1) - rack (~> 1.6) - rack-test (~> 0.6.2) - rails-dom-testing (~> 1.0, >= 1.0.5) - rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (4.2.11.1) - activesupport (= 4.2.11.1) + rails-dom-testing (~> 2.0) + actionpack (6.0.3.2) + actionview (= 6.0.3.2) + activesupport (= 6.0.3.2) + rack (~> 2.0, >= 2.0.8) + rack-test (>= 0.6.3) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.2.0) + actiontext (6.0.3.2) + actionpack (= 6.0.3.2) + activerecord (= 6.0.3.2) + activestorage (= 6.0.3.2) + activesupport (= 6.0.3.2) + nokogiri (>= 1.8.5) + actionview (6.0.3.2) + activesupport (= 6.0.3.2) builder (~> 3.1) - erubis (~> 2.7.0) - rails-dom-testing (~> 1.0, >= 1.0.5) - rails-html-sanitizer (~> 1.0, >= 1.0.3) - active_model-errors_details (1.3.1) - activemodel (>= 3.2.13, < 5.0.0) - activesupport - activejob (4.2.11.1) - activesupport (= 4.2.11.1) - globalid (>= 0.3.0) - activemodel (4.2.11.1) - activesupport (= 4.2.11.1) - builder (~> 3.1) - activerecord (4.2.11.1) - activemodel (= 4.2.11.1) - activesupport (= 4.2.11.1) - arel (~> 6.0) - activerecord-import (0.7.0) - activerecord (>= 3.0) - activesupport (4.2.11.1) - i18n (~> 0.7) + erubi (~> 1.4) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.1, >= 1.2.0) + activejob (6.0.3.2) + activesupport (= 6.0.3.2) + globalid (>= 0.3.6) + activemodel (6.0.3.2) + activesupport (= 6.0.3.2) + activerecord (6.0.3.2) + activemodel (= 6.0.3.2) + activesupport (= 6.0.3.2) + activerecord-import (1.0.5) + activerecord (>= 3.2) + activestorage (6.0.3.2) + actionpack (= 6.0.3.2) + activejob (= 6.0.3.2) + activerecord (= 6.0.3.2) + marcel (~> 0.3.1) + activesupport (6.0.3.2) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) minitest (~> 5.1) - thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - addressable (2.6.0) - public_suffix (>= 2.0.2, < 4.0) - airbrake (6.0.0) - airbrake-ruby (~> 2.0) - airbrake-ruby (2.0.0) + zeitwerk (~> 2.2, >= 2.2.2) + addressable (2.7.0) + public_suffix (>= 2.0.2, < 5.0) + airbrake (10.0.5) + airbrake-ruby (~> 4.13) + airbrake-ruby (4.15.0) + rbtree3 (~> 0.5) akami (1.3.1) gyoku (>= 0.4.0) nokogiri - arel (6.0.4) - autodoc (0.6.0) + autodoc (0.7.4) actionpack activesupport (>= 3.0.0) rspec - autoprefixer-rails (9.4.8) + autoprefixer-rails (9.8.4) execjs - axiom-types (0.1.1) - descendants_tracker (~> 0.0.4) - ice_nine (~> 0.11.0) - thread_safe (~> 0.3, >= 0.3.1) - bcrypt (3.1.12) + bcrypt (3.1.13) + bootsnap (1.4.6) + msgpack (~> 1.0) bootstrap-sass (3.4.1) autoprefixer-rails (>= 5.2.1) sassc (>= 2.0.0) - builder (3.2.3) - bullet (4.14.7) - activesupport (>= 3.0.0) - uniform_notifier (~> 1.9.0) - cancancan (1.11.0) - capybara (3.22.0) + builder (3.2.4) + cancancan (3.1.0) + capybara (3.33.0) addressable mini_mime (>= 0.1.3) nokogiri (~> 1.8) @@ -131,248 +155,263 @@ GEM rack-test (>= 0.6.3) regexp_parser (~> 1.5) xpath (~> 3.2) - childprocess (0.9.0) - ffi (~> 1.0, >= 1.0.11) + childprocess (3.0.0) chronic (0.10.2) coderay (1.1.0) - coercible (1.0.0) - descendants_tracker (~> 0.0.1) - coffee-rails (4.1.0) + coffee-rails (5.0.0) coffee-script (>= 2.2.0) - railties (>= 4.0.0, < 5.0) + railties (>= 5.2.0) coffee-script (2.4.1) coffee-script-source execjs coffee-script-source (1.12.2) - concurrent-ruby (1.1.5) - countries (3.0.0) - i18n_data (~> 0.8.0) + concurrent-ruby (1.1.6) + countries (3.0.1) + i18n_data (~> 0.10.0) sixarm_ruby_unaccent (~> 1.1) unicode_utils (~> 1.4) crack (0.4.3) safe_yaml (~> 1.0.0) - crass (1.0.4) - daemons (1.2.4) + crass (1.0.6) + daemons (1.3.1) daemons-rails (1.2.1) daemons multi_json (~> 1.0) - database_cleaner (1.6.1) - descendants_tracker (0.0.4) - thread_safe (~> 0.3, >= 0.3.1) - devise (4.6.1) + data_migrate (6.3.0) + rails (>= 5.0) + database_cleaner (1.8.5) + devise (4.7.2) bcrypt (~> 3.0) orm_adapter (~> 0.1) - railties (>= 4.1.0, < 6.0) + railties (>= 4.1.0) responders warden (~> 1.2.3) - diff-lcs (1.3) - docile (1.3.1) - domain_name (0.5.20170404) + diff-lcs (1.4.4) + docile (1.3.2) + domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) - equalizer (0.0.11) + dry-configurable (0.11.6) + concurrent-ruby (~> 1.0) + dry-core (~> 0.4, >= 0.4.7) + dry-equalizer (~> 0.2) + dry-container (0.7.2) + concurrent-ruby (~> 1.0) + dry-configurable (~> 0.1, >= 0.1.3) + dry-core (0.4.9) + concurrent-ruby (~> 1.0) + dry-equalizer (0.3.0) + dry-inflector (0.2.0) + dry-logic (1.0.6) + concurrent-ruby (~> 1.0) + dry-core (~> 0.2) + dry-equalizer (~> 0.2) + dry-types (1.4.0) + concurrent-ruby (~> 1.0) + dry-container (~> 0.3) + dry-core (~> 0.4, >= 0.4.4) + dry-equalizer (~> 0.3) + dry-inflector (~> 0.1, >= 0.1.2) + dry-logic (~> 1.0, >= 1.0.2) + erubi (1.9.0) erubis (2.7.0) execjs (2.7.0) - factory_bot (4.8.2) - activesupport (>= 3.0.0) - factory_bot_rails (4.8.2) - factory_bot (~> 4.8.2) - railties (>= 3.0.0) - ffi (1.9.25) + ffi (1.13.1) figaro (1.1.1) thor (~> 0.14) globalid (0.4.2) activesupport (>= 4.2.0) - grape (1.2.3) + grape (1.3.3) activesupport builder + dry-types (>= 1.1) mustermann-grape (~> 1.0.0) rack (>= 1.3.0) rack-accept - virtus (>= 1.0.0) gyoku (1.3.1) builder (>= 2.1.2) - haml (4.0.7) + haml (5.1.2) + temple (>= 0.8.0) tilt - haml-rails (0.9.0) - actionpack (>= 4.0.1) - activesupport (>= 4.0.1) - haml (>= 4.0.6, < 5.0) - html2haml (>= 1.0.1) - railties (>= 4.0.1) - hashdiff (0.4.0) + hashdiff (1.0.1) hpricot (0.8.6) - html2haml (2.1.0) - erubis (~> 2.7.0) - haml (~> 4.0) - nokogiri (>= 1.6.0) - ruby_parser (~> 3.5) + http-accept (1.7.0) http-cookie (1.0.3) domain_name (~> 0.5) httpclient (2.8.3) httpi (2.4.4) rack socksify - i18n (0.9.5) + i18n (1.8.3) concurrent-ruby (~> 1.0) - i18n_data (0.8.0) - ice_nine (0.11.2) + i18n_data (0.10.0) isikukood (0.1.2) - iso8601 (0.8.6) - jbuilder (2.2.16) - activesupport (>= 3.0.0, < 5) - multi_json (~> 1.2) - jquery-rails (4.0.4) - rails-dom-testing (~> 1.0) + iso8601 (0.12.1) + jquery-rails (4.4.0) + rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) jquery-ui-rails (5.0.5) railties (>= 3.2.16) - json (1.8.6) - kaminari (0.16.3) - actionpack (>= 3.0.0) - activesupport (>= 3.0.0) - libxml-ruby (3.0.0) - loofah (2.2.3) + json (2.3.1) + kaminari (1.2.1) + activesupport (>= 4.1.0) + kaminari-actionview (= 1.2.1) + kaminari-activerecord (= 1.2.1) + kaminari-core (= 1.2.1) + kaminari-actionview (1.2.1) + actionview + kaminari-core (= 1.2.1) + kaminari-activerecord (1.2.1) + activerecord + kaminari-core (= 1.2.1) + kaminari-core (1.2.1) + libxml-ruby (3.2.0) + listen (3.2.1) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + logger (1.4.2) + loofah (2.6.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) + marcel (0.3.3) + mimemagic (~> 0.3.2) method_source (0.8.2) - mime-types (3.1) + mime-types (3.3.1) mime-types-data (~> 3.2015) - mime-types-data (3.2016.0521) + mime-types-data (3.2020.0512) + mimemagic (0.3.5) mina (0.3.1) open4 (~> 1.3.4) rake - mini_mime (1.0.1) + mini_mime (1.0.2) mini_portile2 (2.4.0) - minitest (5.11.3) - monetize (1.9.0) + minitest (5.14.1) + monetize (1.9.4) money (~> 6.12) - money (6.12.0) - i18n (>= 0.6.4, < 1.1) - money-rails (1.12.0) + money (6.13.8) + i18n (>= 0.6.4, <= 2) + money-rails (1.13.3) activesupport (>= 3.0) monetize (~> 1.9.0) - money (~> 6.12.0) + money (~> 6.13.2) railties (>= 3.0) - multi_json (1.13.1) - mustermann (1.0.3) - mustermann-grape (1.0.0) - mustermann (~> 1.0.0) + msgpack (1.3.3) + multi_json (1.14.1) + mustermann (1.1.1) + ruby2_keywords (~> 0.0.1) + mustermann-grape (1.0.1) + mustermann (>= 1.0.0) netrc (0.11.0) - nokogiri (1.10.3) + nio4r (2.5.2) + nokogiri (1.10.10) mini_portile2 (~> 2.4.0) nori (2.6.0) open4 (1.3.4) orm_adapter (0.5.0) - paper_trail (4.2.0) - activerecord (>= 3.0, < 6.0) - activesupport (>= 3.0, < 6.0) + paper_trail (10.3.1) + activerecord (>= 4.2) request_store (~> 1.1) - pdfkit (0.8.4.1) - pg (0.19.0) - polyamorous (1.3.1) - activerecord (>= 3.0) + pdfkit (0.8.4.3.1) + pg (1.2.2) + polyamorous (2.3.2) + activerecord (>= 5.2.1) pry (0.10.1) coderay (~> 1.1.0) method_source (~> 0.8.1) slop (~> 3.4) - public_suffix (3.1.0) - puma (3.12.1) - que (0.10.0) - que-web (0.4.0) + public_suffix (4.0.5) + puma (4.3.5) + nio4r (~> 2.0) + que (0.14.3) + que-web (0.7.2) erubis que (~> 0.8) sinatra - rack (1.6.11) + rack (2.2.3) rack-accept (0.4.5) rack (>= 0.4) - rack-protection (1.5.5) + rack-protection (2.0.8.1) rack - rack-test (0.6.3) - rack (>= 1.0) + rack-test (1.1.0) + rack (>= 1.0, < 3) railroady (1.3.0) - rails (4.2.11.1) - actionmailer (= 4.2.11.1) - actionpack (= 4.2.11.1) - actionview (= 4.2.11.1) - activejob (= 4.2.11.1) - activemodel (= 4.2.11.1) - activerecord (= 4.2.11.1) - activesupport (= 4.2.11.1) - bundler (>= 1.3.0, < 2.0) - railties (= 4.2.11.1) - sprockets-rails - rails-deprecated_sanitizer (1.0.3) - activesupport (>= 4.2.0.alpha) - rails-dom-testing (1.0.9) - activesupport (>= 4.2.0, < 5.0) - nokogiri (~> 1.6) - rails-deprecated_sanitizer (>= 1.0.1) - rails-html-sanitizer (1.0.4) - loofah (~> 2.2, >= 2.2.2) - rails-settings-cached (0.7.2) - rails (>= 4.2.0) - railties (4.2.11.1) - actionpack (= 4.2.11.1) - activesupport (= 4.2.11.1) + rails (6.0.3.2) + actioncable (= 6.0.3.2) + actionmailbox (= 6.0.3.2) + actionmailer (= 6.0.3.2) + actionpack (= 6.0.3.2) + actiontext (= 6.0.3.2) + actionview (= 6.0.3.2) + activejob (= 6.0.3.2) + activemodel (= 6.0.3.2) + activerecord (= 6.0.3.2) + activestorage (= 6.0.3.2) + activesupport (= 6.0.3.2) + bundler (>= 1.3.0) + railties (= 6.0.3.2) + sprockets-rails (>= 2.0.0) + rails-dom-testing (2.0.3) + activesupport (>= 4.2.0) + nokogiri (>= 1.6) + rails-html-sanitizer (1.3.0) + loofah (~> 2.3) + railties (6.0.3.2) + actionpack (= 6.0.3.2) + activesupport (= 6.0.3.2) + method_source rake (>= 0.8.7) - thor (>= 0.18.1, < 2.0) - rake (12.3.2) - ransack (1.5.1) - actionpack (>= 3.0) - activerecord (>= 3.0) - activesupport (>= 3.0) + thor (>= 0.20.3, < 2.0) + rake (13.0.1) + ransack (2.3.2) + activerecord (>= 5.2.1) + activesupport (>= 5.2.1) i18n - polyamorous (~> 1.1) - rdoc (4.3.0) - regexp_parser (1.5.1) - request_store (1.4.1) + polyamorous (= 2.3.2) + rb-fsevent (0.10.4) + rb-inotify (0.10.1) + ffi (~> 1.0) + rbtree3 (0.6.0) + rdoc (6.2.1) + regexp_parser (1.7.1) + request_store (1.5.0) rack (>= 1.4) - responders (2.4.1) - actionpack (>= 4.2.0, < 6.0) - railties (>= 4.2.0, < 6.0) - rest-client (2.0.1) + responders (3.0.1) + actionpack (>= 5.0) + railties (>= 5.0) + rest-client (2.1.0) + http-accept (>= 1.7.0, < 2.0) http-cookie (>= 1.0.2, < 2.0) mime-types (>= 1.16, < 4.0) netrc (~> 0.8) - rspec (3.6.0) - rspec-core (~> 3.6.0) - rspec-expectations (~> 3.6.0) - rspec-mocks (~> 3.6.0) - rspec-core (3.6.0) - rspec-support (~> 3.6.0) - rspec-expectations (3.6.0) + rspec (3.9.0) + rspec-core (~> 3.9.0) + rspec-expectations (~> 3.9.0) + rspec-mocks (~> 3.9.0) + rspec-core (3.9.2) + rspec-support (~> 3.9.3) + rspec-expectations (3.9.2) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.6.0) - rspec-mocks (3.6.0) + rspec-support (~> 3.9.0) + rspec-mocks (3.9.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.6.0) - rspec-rails (3.6.0) - actionpack (>= 3.0) - activesupport (>= 3.0) - railties (>= 3.0) - rspec-core (~> 3.6.0) - rspec-expectations (~> 3.6.0) - rspec-mocks (~> 3.6.0) - rspec-support (~> 3.6.0) - rspec-support (3.6.0) - ruby_parser (3.8.4) - sexp_processor (~> 4.1) - rubyzip (1.2.2) + rspec-support (~> 3.9.0) + rspec-support (3.9.3) + ruby2_keywords (0.0.2) + rubyzip (2.3.0) safe_yaml (1.0.5) - sass (3.4.23) - sass-rails (5.0.6) - railties (>= 4.0.0, < 6) - sass (~> 3.1) - sprockets (>= 2.8, < 4.0) - sprockets-rails (>= 2.0, < 4.0) - tilt (>= 1.1, < 3) - sassc (2.0.0) - ffi (~> 1.9.6) - rake - savon (2.12.0) + sass-rails (6.0.0) + sassc-rails (~> 2.1, >= 2.1.1) + sassc (2.4.0) + ffi (~> 1.9) + sassc-rails (2.1.2) + railties (>= 4.0.0) + sassc (>= 2.0) + sprockets (> 3.0) + sprockets-rails + tilt + savon (2.12.1) akami (~> 1.2) builder (>= 2.1.2) gyoku (~> 1.2) @@ -380,133 +419,138 @@ GEM nokogiri (>= 1.8.1) nori (~> 2.4) wasabi (~> 3.4) - sdoc (0.4.1) - json (~> 1.7, >= 1.7.7) - rdoc (~> 4.0) + sdoc (1.1.0) + rdoc (>= 5.0) select2-rails (3.5.9.3) thor (~> 0.14) selectize-rails (0.12.1) - selenium-webdriver (3.13.0) - childprocess (~> 0.5) - rubyzip (~> 1.2) - sexp_processor (4.8.0) - simplecov (0.16.1) + selenium-webdriver (3.142.7) + childprocess (>= 0.5, < 4.0) + rubyzip (>= 1.2.2) + simplecov (0.17.1) docile (~> 1.1) json (>= 1.8, < 3) simplecov-html (~> 0.10.0) simplecov-html (0.10.2) - simpleidn (0.0.7) - sinatra (1.4.8) - rack (~> 1.5) - rack-protection (~> 1.4) - tilt (>= 1.3, < 3) + simpleidn (0.1.1) + unf (~> 0.1.4) + sinatra (2.0.8.1) + mustermann (~> 1.0) + rack (~> 2.0) + rack-protection (= 2.0.8.1) + tilt (~> 2.0) sixarm_ruby_unaccent (1.2.0) slop (3.6.0) socksify (1.7.1) - sprockets (3.7.2) + sprockets (4.0.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) sprockets-rails (3.2.1) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) + temple (0.8.2) thor (0.20.3) thread_safe (0.3.6) - tilt (1.4.1) - tzinfo (1.2.5) + tilt (2.0.10) + truemail (1.8.0) + simpleidn (~> 0.1.1) + tzinfo (1.2.7) thread_safe (~> 0.1) - uglifier (4.1.11) + uglifier (4.2.0) execjs (>= 0.3.0, < 3) unf (0.1.4) unf_ext - unf_ext (0.0.7.2) + unf_ext (0.0.7.7) unicode_utils (1.4.0) - uniform_notifier (1.9.0) - uuidtools (2.1.5) validates_email_format_of (1.6.3) i18n - virtus (1.0.5) - axiom-types (~> 0.1) - coercible (~> 1.0) - descendants_tracker (~> 0.0, >= 0.0.3) - equalizer (~> 0.0, >= 0.0.9) - warden (1.2.7) - rack (>= 1.0) + warden (1.2.8) + rack (>= 2.0.6) wasabi (3.5.0) httpi (~> 2.0) nokogiri (>= 1.4.2) - webmock (3.6.0) + webdrivers (4.4.1) + nokogiri (~> 1.6) + rubyzip (>= 1.3.0) + selenium-webdriver (>= 3.0, < 4.0) + webmock (3.8.3) addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) + websocket-driver (0.7.2) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.5) whenever (0.9.4) chronic (>= 0.6.3) + wkhtmltopdf-binary (0.12.5.4) xpath (3.2.0) nokogiri (~> 1.8) + zeitwerk (2.3.1) PLATFORMS ruby DEPENDENCIES - active_model-errors_details - activerecord-import (= 0.7.0) + activerecord-import airbrake autodoc + bootsnap (>= 1.1.0) bootstrap-sass (~> 3.4) - bullet (= 4.14.7) - cancancan (= 1.11.0) + cancancan capybara coderay (= 1.1.0) - coffee-rails (= 4.1.0) + coffee-rails (>= 5.0) company_register! countries daemons-rails (= 1.2.1) - data_migrate! + data_migrate (~> 6.1) database_cleaner - devise (~> 4.0) + devise (~> 4.7) digidoc_client! + directo! + domain_name e_invoice! - epp (= 1.5.0)! + epp! epp-xml (= 1.1.0)! - factory_bot_rails figaro (= 1.1.1) grape - haml-rails (= 0.9.0) - html2haml (= 2.1.0) + haml (~> 5.0) isikukood - iso8601 (= 0.8.6) - jbuilder (= 2.2.16) - jquery-rails (= 4.0.4) + iso8601 (= 0.12.1) + jquery-rails jquery-ui-rails (= 5.0.5) - kaminari (= 0.16.3) + kaminari + lhv! + listen (= 3.2.1) mina (= 0.3.1) + minitest (~> 5.14) money-rails nokogiri - paper_trail (~> 4.0) + paper_trail (~> 10.3) pdfkit - pg (= 0.19.0) + pg (= 1.2.2) pry (= 0.10.1) puma - que (= 0.10.0) - que-web (= 0.4.0) + que + que-web railroady (= 1.3.0) - rails (= 4.2.11.1) - rails-settings-cached (= 0.7.2) - ransack (= 1.5.1) + rails (~> 6.0) + ransack (~> 2.3) rest-client - rspec-rails (~> 3.6) - sass-rails (= 5.0.6) - sdoc (= 0.4.1) + sass-rails + sdoc (~> 1.1) select2-rails (= 3.5.9.3) selectize-rails (= 0.12.1) - selenium-webdriver - simplecov - simpleidn (= 0.0.7) + simplecov (= 0.17.1) + simpleidn (= 0.1.1) + truemail (~> 1.7) uglifier - uuidtools (= 2.1.5) validates_email_format_of (= 1.6.3) + webdrivers webmock whenever (= 0.9.4) + wkhtmltopdf-binary (~> 0.12.5.1) BUNDLED WITH - 1.17.3 + 2.1.4 diff --git a/README.md b/README.md index e2ba0b90f..774e35331 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ Domain Registry =============== [![Build Status](https://travis-ci.org/internetee/registry.svg?branch=master)](https://travis-ci.org/internetee/registry) -[![Code Climate](https://codeclimate.com/github/internetee/registry/badges/gpa.svg)](https://codeclimate.com/github/internetee/registry) -[![Test Coverage](https://codeclimate.com/github/internetee/registry/badges/coverage.svg)](https://codeclimate.com/github/internetee/registry/coverage) +[![Maintainability](https://api.codeclimate.com/v1/badges/a91e4ae502a6c5245160/maintainability)](https://codeclimate.com/github/internetee/registry/maintainability) +[![Test Coverage](https://api.codeclimate.com/v1/badges/a91e4ae502a6c5245160/test_coverage)](https://codeclimate.com/github/internetee/registry/test_coverage) [![Documentation Status](https://readthedocs.org/projects/eeregistry/badge/?version=latest)](http://docs.internet.ee/en/latest/?badge=latest) Full stack top-level domain (TLD) management. @@ -17,15 +17,15 @@ Documentation ------------- * [EPP documentation](/doc/epp) -* [EPP request-response examples](/doc/epp-examples.md) -* [REPP documentation](/doc/repp-doc.md) +* [EPP request-response examples](/doc/epp_examples.md) +* [REPP documentation](/doc/repp_doc.md) * [Database diagram](/doc/models_complete.svg) * [Controllers diagram](/doc/controllers_complete.svg) ### Updating documentation AUTODOC=true rspec spec/requests - EPP_DOC=true rspec spec/epp --tag epp --require support/epp_doc.rb --format EppDoc > doc/epp-examples.md + EPP_DOC=true rspec spec/epp --tag epp --require support/epp_doc.rb --format EppDoc > doc/epp_examples.md Installation ------------ @@ -41,8 +41,8 @@ Manual demo install and database setup: cd demo-registry rbenv local 2.2.2 bundle - cp config/application-example.yml config/application.yml # and edit it - cp config/database-example.yml config/database.yml # and edit it + cp config/application.yml.sample config/application.yml # and edit it + cp config/database.yml.sample config/database.yml # and edit it bundle exec rake db:setup:all # for production, please follow deployment howto bundle exec rake bootstrap bundle exec rake assets:precompile diff --git a/Rakefile b/Rakefile index ba6b733dd..e85f91391 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,6 @@ # Add your own tasks in files placed in lib/tasks ending in .rake, # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. -require File.expand_path('../config/application', __FILE__) +require_relative 'config/application' Rails.application.load_tasks diff --git a/app/api/repp/api.rb b/app/api/repp/api.rb index e5bda46f5..af6864cfa 100644 --- a/app/api/repp/api.rb +++ b/app/api/repp/api.rb @@ -30,7 +30,8 @@ module Repp webclient_cert_name = ENV['webclient_cert_common_name'] || 'webclient' error! "Webclient #{message} #{webclient_cert_name}", 401 if webclient_cert_name != request_name else - unless @current_user.api_pki_ok?(request.env['HTTP_SSL_CLIENT_CERT'], request.env['HTTP_SSL_CLIENT_S_DN_CN']) + unless @current_user.pki_ok?(request.env['HTTP_SSL_CLIENT_CERT'], + request.env['HTTP_SSL_CLIENT_S_DN_CN']) error! "#{message} #{@current_user.username}", 401 end end diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js new file mode 100644 index 000000000..89c89e752 --- /dev/null +++ b/app/assets/config/manifest.js @@ -0,0 +1,3 @@ + //= link_tree ../images + //= link_directory ../javascripts .js + //= link_directory ../stylesheets .css diff --git a/app/assets/javascripts/admin/autocomplete.js.coffee b/app/assets/javascripts/admin/autocomplete.js.coffee index 84708055c..2308c1d28 100644 --- a/app/assets/javascripts/admin/autocomplete.js.coffee +++ b/app/assets/javascripts/admin/autocomplete.js.coffee @@ -47,12 +47,6 @@ class @Autocomplete selector: '.js-contact-typeahead' hiddenSelector: '.js-contact-id' - @bindAdminRegistrarSearch: -> - Autocomplete.bindTypeahead - remote: '/admin/registrars/search' - selector: '.js-registrar-typeahead' - hiddenSelector: '.js-registrar-id' - @bindClientContactSearch: -> Autocomplete.bindTypeahead remote: '/client/contacts/search' diff --git a/app/assets/stylesheets/admin/admin.sass b/app/assets/stylesheets/admin/admin.sass index fe9b569ff..ddb3fe673 100644 --- a/app/assets/stylesheets/admin/admin.sass +++ b/app/assets/stylesheets/admin/admin.sass @@ -133,12 +133,6 @@ body.login padding-top: 40px padding-bottom: 40px - .form-signin - .form-signin-heading, - .form-signin - .checkbox - margin-bottom: 10px - .form-signin max-width: 330px padding: 15px diff --git a/app/assets/stylesheets/shared/general.sass b/app/assets/stylesheets/shared/general.sass index 07b92cdbe..6d1c4956d 100644 --- a/app/assets/stylesheets/shared/general.sass +++ b/app/assets/stylesheets/shared/general.sass @@ -15,6 +15,9 @@ body > .container padding-top: 15px font-size: 10px +a.footer-version-link + color: black + .nowrap white-space: nowrap diff --git a/app/controllers/admin/account_activities_controller.rb b/app/controllers/admin/account_activities_controller.rb index 6a37e36dc..e022843ff 100644 --- a/app/controllers/admin/account_activities_controller.rb +++ b/app/controllers/admin/account_activities_controller.rb @@ -23,11 +23,11 @@ module Admin @q.sorts = 'id desc' if @q.sorts.empty? @account_activities = @q.result.page(params[:page]).per(params[:results_per_page]) - sort = @account_activities.orders.map(&:to_sql).join(",") - # can do here inline SQL as it's our if params[:page] && params[:page].to_i > 1 - @sum = @q.result.reorder(sort).limit(@account_activities.offset_value).sum(:sum) + @b.result.where("account_activities.id NOT IN (#{@q.result.select(:id).to_sql})").sum(:sum) + @sum = @q.result.limit(@account_activities.offset_value).sum(:sum) + + @b.result.where("account_activities.id NOT IN (#{@q.result.select(:id).to_sql})") + .sum(:sum) else @sum = @b.result.where("account_activities.id NOT IN (#{@q.result.select(:id).to_sql})").sum(:sum) end diff --git a/app/controllers/admin/api_users_controller.rb b/app/controllers/admin/api_users_controller.rb index bbf0a8a4e..8876c726f 100644 --- a/app/controllers/admin/api_users_controller.rb +++ b/app/controllers/admin/api_users_controller.rb @@ -1,7 +1,6 @@ module Admin class ApiUsersController < BaseController load_and_authorize_resource - before_action :set_api_user, only: [:show, :edit, :update, :destroy] def index @q = ApiUser.includes(:registrar).search(params[:q]) @@ -9,18 +8,17 @@ module Admin end def new - @registrar = Registrar.find_by(id: params[:registrar_id]) - @api_user = ApiUser.new(registrar: @registrar) + @api_user = registrar.api_users.build end def create - @api_user = ApiUser.new(api_user_params) + @api_user = registrar.api_users.build(api_user_params) - if @api_user.save - flash[:notice] = I18n.t('record_created') - redirect_to [:admin, @api_user] + if @api_user.valid? + @api_user.save! + redirect_to admin_registrar_api_user_path(@api_user.registrar, @api_user), + notice: t('.created') else - flash.now[:alert] = I18n.t('failed_to_create_record') render 'new' end end @@ -32,39 +30,31 @@ module Admin end def update - if params[:api_user][:plain_text_password].blank? - params[:api_user].delete(:plain_text_password) - end + @api_user.attributes = api_user_params - if @api_user.update(api_user_params) - flash[:notice] = I18n.t('record_updated') - redirect_to [:admin, @api_user] + if @api_user.valid? + @api_user.save! + redirect_to admin_registrar_api_user_path(@api_user.registrar, @api_user), + notice: t('.updated') else - flash.now[:alert] = I18n.t('failed_to_update_record') render 'edit' end end def destroy - if @api_user.destroy - flash[:notice] = I18n.t('record_deleted') - redirect_to admin_api_users_path - else - flash.now[:alert] = I18n.t('failed_to_delete_record') - render 'show' - end + @api_user.destroy! + redirect_to admin_registrar_path(@api_user.registrar), notice: t('.deleted') end private - def set_api_user - @api_user = ApiUser.find(params[:id]) - end - def api_user_params params.require(:api_user).permit(:username, :plain_text_password, :active, - :registrar_id, :registrar_typeahead, :identity_code, { roles: [] }) end + + def registrar + Registrar.find(params[:registrar_id]) + end end end diff --git a/app/controllers/admin/bank_statements_controller.rb b/app/controllers/admin/bank_statements_controller.rb index a70387317..1e3b31bf5 100644 --- a/app/controllers/admin/bank_statements_controller.rb +++ b/app/controllers/admin/bank_statements_controller.rb @@ -60,7 +60,7 @@ module Admin end def bind_invoices - @bank_statement.bind_invoices + @bank_statement.bind_invoices(manual: true) flash[:notice] = t('invoices_were_fully_binded') if @bank_statement.fully_binded? flash[:warning] = t('invoices_were_partially_binded') if @bank_statement.partially_binded? diff --git a/app/controllers/admin/bank_transactions_controller.rb b/app/controllers/admin/bank_transactions_controller.rb index 1ce62b279..348cadc64 100644 --- a/app/controllers/admin/bank_transactions_controller.rb +++ b/app/controllers/admin/bank_transactions_controller.rb @@ -34,7 +34,7 @@ module Admin end def bind - if @bank_transaction.bind_invoice(params[:invoice_no]) + if @bank_transaction.bind_invoice(params[:invoice_no], manual: true) flash[:notice] = I18n.t('record_created') redirect_to [:admin, @bank_transaction] else diff --git a/app/controllers/admin/base_controller.rb b/app/controllers/admin/base_controller.rb index 17e75785a..1fec2a18f 100644 --- a/app/controllers/admin/base_controller.rb +++ b/app/controllers/admin/base_controller.rb @@ -2,6 +2,7 @@ module Admin class BaseController < ApplicationController before_action :authenticate_admin_user! helper_method :head_title_sufix + before_action :set_paper_trail_whodunnit def head_title_sufix t(:admin_head_title_sufix) @@ -17,4 +18,4 @@ module Admin current_admin_user ? current_admin_user.id_role_username : 'anonymous' end end -end \ No newline at end of file +end diff --git a/app/controllers/admin/certificates_controller.rb b/app/controllers/admin/certificates_controller.rb index 636a69367..d338b2e9f 100644 --- a/app/controllers/admin/certificates_controller.rb +++ b/app/controllers/admin/certificates_controller.rb @@ -34,7 +34,7 @@ module Admin if @certificate.destroy flash[:notice] = I18n.t('record_deleted') - redirect_to admin_api_user_path(@api_user) + redirect_to admin_registrar_api_user_path(@api_user.registrar, @api_user) else flash.now[:alert] = I18n.t('failed_to_delete_record') render 'show' diff --git a/app/controllers/admin/contacts_controller.rb b/app/controllers/admin/contacts_controller.rb index b53d366ab..793fa1209 100644 --- a/app/controllers/admin/contacts_controller.rb +++ b/app/controllers/admin/contacts_controller.rb @@ -3,6 +3,7 @@ module Admin load_and_authorize_resource before_action :set_contact, only: [:show] helper_method :ident_types + helper_method :domain_filter_params def index params[:q] ||= {} @@ -12,19 +13,27 @@ module Admin search_params[:registrant_domains_id_not_null] = 1 end - contacts = Contact.includes(:registrar).joins(:registrar).select('contacts.*, registrars.name') + contacts = Contact.includes(:registrar).joins(:registrar) + .select('contacts.*, registrars.name') contacts = contacts.filter_by_states(params[:statuses_contains].join(',')) if params[:statuses_contains] - contacts = contacts.where("ident_country_code is null or ident_country_code=''") if params[:only_no_country_code].eql?('1') - + contacts = filter_by_flags(contacts) normalize_search_parameters do @q = contacts.search(search_params) - @contacts = @q.result.uniq.page(params[:page]) + @contacts = @q.result.distinct.page(params[:page]) end @contacts = @contacts.per(params[:results_per_page]) if params[:results_per_page].to_i.positive? end + def filter_by_flags(contacts) + if params[:only_no_country_code].eql?('1') + contacts = contacts.where("ident_country_code is null or ident_country_code=''") + end + contacts = contacts.email_verification_failed if params[:email_verification_failed].eql?('1') + contacts + end + def search render json: Contact.search_by_query(params[:q]) end @@ -84,5 +93,9 @@ module Admin def ident_types Contact::Ident.types end + + def domain_filter_params + params.permit(:domain_filter) + end end end diff --git a/app/controllers/admin/disputes_controller.rb b/app/controllers/admin/disputes_controller.rb new file mode 100644 index 000000000..8a8997f63 --- /dev/null +++ b/app/controllers/admin/disputes_controller.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +module Admin + class DisputesController < BaseController + load_and_authorize_resource + before_action :set_dispute, only: %i[show edit update delete] + + # GET /admin/disputes + def index + params[:q] ||= {} + @disputes = sortable_dispute_query_for(Dispute.active.all, params[:q]) + @closed_disputes = sortable_dispute_query_for(Dispute.closed.all, params[:q], closed: true) + end + + # GET /admin/disputes/1 + def show; end + + # GET /admin/disputes/new + def new + @dispute = Dispute.new + end + + # GET /admin/disputes/1/edit + def edit; end + + # POST /admin/disputes + def create + @dispute = Dispute.new(dispute_params) + if @dispute.save + notice = 'Dispute was successfully created' + notice += @dispute.domain ? '.' : ' for domain that is not registered.' + + redirect_to admin_disputes_url, notice: notice + else + render :new + end + end + + # PATCH/PUT /admin/disputes/1 + def update + if @dispute.update(dispute_params.except(:domain_name)) + redirect_to admin_disputes_url, notice: 'Dispute was successfully updated.' + else + render :edit + end + end + + # DELETE /admin/disputes/1 + def delete + @dispute.close(initiator: 'Admin') + redirect_to admin_disputes_url, notice: 'Dispute was successfully closed.' + end + + private + + def sortable_dispute_query_for(disputes, query, closed: false) + @q = disputes.order(:domain_name).search(query) + disputes = @q.result.page(closed ? params[:closed_page] : params[:page]) + return disputes.per(params[:results_per_page]) if params[:results_per_page].present? + + disputes + end + + # Use callbacks to share common setup or constraints between actions. + def set_dispute + @dispute = Dispute.find(params[:id]) + end + + # Only allow a trusted parameter "white list" through. + def dispute_params + params.require(:dispute).permit(:domain_name, :password, :starts_at, :comment) + end + end +end diff --git a/app/controllers/admin/domains/force_delete_controller.rb b/app/controllers/admin/domains/force_delete_controller.rb index 946231077..c61f050d2 100644 --- a/app/controllers/admin/domains/force_delete_controller.rb +++ b/app/controllers/admin/domains/force_delete_controller.rb @@ -5,21 +5,27 @@ module Admin authorize! :manage, domain domain.transaction do - domain.schedule_force_delete + domain.schedule_force_delete(type: force_delete_type) domain.registrar.notifications.create!(text: t('force_delete_set_on_domain', - domain_name: domain.name)) + domain_name: domain.name, + outzone_date: domain.outzone_date, + purge_date: domain.purge_date)) - if notify_by_email? - DomainDeleteMailer.forced(domain: domain, - registrar: domain.registrar, - registrant: domain.registrant, - template_name: params[:template_name]).deliver_now - end + notify_by_email if notify_by_email? end redirect_to edit_admin_domain_url(domain), notice: t('.scheduled') end + def notify_by_email + if force_delete_type == :fast_track + send_email + domain.update(contact_notification_sent_date: Time.zone.today) + else + domain.update(template_name: params[:template_name]) + end + end + def destroy authorize! :manage, domain domain.cancel_force_delete @@ -33,7 +39,22 @@ module Admin end def notify_by_email? - ActiveRecord::Type::Boolean.new.type_cast_from_user(params[:notify_by_email]) + ActiveRecord::Type::Boolean.new.cast(params[:notify_by_email]) + end + + def send_email + DomainDeleteMailer.forced(domain: domain, + registrar: domain.registrar, + registrant: domain.registrant, + template_name: params[:template_name]).deliver_now + end + + def force_delete_type + soft_delete? ? :soft : :fast_track + end + + def soft_delete? + ActiveRecord::Type::Boolean.new.cast(params[:soft_delete]) end end end diff --git a/app/controllers/admin/keyrelays_controller.rb b/app/controllers/admin/keyrelays_controller.rb deleted file mode 100644 index c6049373f..000000000 --- a/app/controllers/admin/keyrelays_controller.rb +++ /dev/null @@ -1,13 +0,0 @@ -module Admin - class KeyrelaysController < BaseController - load_and_authorize_resource - - def index - @q = Keyrelay.includes(:requester, :accepter).search(params[:q]) - @keyrelays = @q.result.page(params[:page]) - end - - def show; - end - end -end diff --git a/app/controllers/admin/legal_documents_controller.rb b/app/controllers/admin/legal_documents_controller.rb index a07949875..68b95877d 100644 --- a/app/controllers/admin/legal_documents_controller.rb +++ b/app/controllers/admin/legal_documents_controller.rb @@ -5,7 +5,11 @@ module Admin def show @ld = LegalDocument.find(params[:id]) filename = @ld.path.split('/').last - send_data File.open(@ld.path).read, filename: filename + file = File.open(@ld.path)&.read + send_data file, filename: filename + rescue Errno::ENOENT + flash[:notice] = I18n.t('legal_doc_not_found') + redirect_to [:admin, @ld.documentable] end end end diff --git a/app/controllers/admin/pending_deletes_controller.rb b/app/controllers/admin/pending_deletes_controller.rb index 9cc8702c5..8e39b306b 100644 --- a/app/controllers/admin/pending_deletes_controller.rb +++ b/app/controllers/admin/pending_deletes_controller.rb @@ -29,7 +29,6 @@ module Admin # steal token token = @domain.registrant_verification_token @registrant_verification = RegistrantVerification.new(domain_id: @domain.id, - domain_name: @domain.name, verification_token: token) end diff --git a/app/controllers/admin/pending_updates_controller.rb b/app/controllers/admin/pending_updates_controller.rb index 4a2e5ec7c..72b1ace6e 100644 --- a/app/controllers/admin/pending_updates_controller.rb +++ b/app/controllers/admin/pending_updates_controller.rb @@ -26,7 +26,6 @@ module Admin # steal token token = @domain.registrant_verification_token @registrant_verification = RegistrantVerification.new(domain_id: @domain.id, - domain_name: @domain.name, verification_token: token) end diff --git a/app/controllers/admin/registrars_controller.rb b/app/controllers/admin/registrars_controller.rb index b925a8156..27116d871 100644 --- a/app/controllers/admin/registrars_controller.rb +++ b/app/controllers/admin/registrars_controller.rb @@ -74,6 +74,8 @@ module Admin :vat_rate, :accounting_customer_code, :billing_email, + :legaldoc_optout, + :legaldoc_optout_comment, :iban, :language) end diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb index 293c994b6..8a5c275c5 100644 --- a/app/controllers/admin/settings_controller.rb +++ b/app/controllers/admin/settings_controller.rb @@ -3,21 +3,23 @@ module Admin load_and_authorize_resource def index - @settings = Setting.unscoped + @settings = SettingEntry.unscoped + @validation_settings = SettingEntry.with_group('domain_validation') + @expiration_settings = SettingEntry.with_group('domain_expiration') + @other_settings = SettingEntry.with_group('other') + .where.not(code: 'default_language') + @billing_settings = SettingEntry.with_group('billing') + @contacts_settings = SettingEntry.with_group('contacts') end def create - @errors = Setting.params_errors(casted_settings) - if @errors.empty? - casted_settings.each do |k, v| - Setting[k] = v - end - + update = SettingEntry.update(casted_settings.keys, casted_settings.values) + if update flash[:notice] = t('.saved') - redirect_to [:admin, :settings] + redirect_to %i[admin settings] else - flash[:alert] = @errors.values.uniq.join(", ") - render "admin/settings/index" + flash[:alert] = update.errors.values.uniq.join(', ') + render 'admin/settings/index' end end @@ -27,10 +29,7 @@ module Admin settings = {} params[:settings].each do |k, v| - settings[k] = v - settings[k] = v.to_i if Setting.integer_settings.include?(k.to_sym) - settings[k] = v.to_f if Setting.float_settings.include?(k.to_sym) - settings[k] = (v == 'true' ? true : false) if Setting.boolean_settings.include?(k.to_sym) + settings[k] = { value: v } end settings diff --git a/app/controllers/admin/zonefiles_controller.rb b/app/controllers/admin/zonefiles_controller.rb index 30b4b9a61..4fd84bb77 100644 --- a/app/controllers/admin/zonefiles_controller.rb +++ b/app/controllers/admin/zonefiles_controller.rb @@ -13,7 +13,7 @@ module Admin send_data @zonefile, filename: "#{params[:origin]}.txt" else flash[:alert] = 'Origin not supported' - redirect_to :back + redirect_back(fallback_location: root_path) end end end diff --git a/app/controllers/api/cors_controller.rb b/app/controllers/api/cors_controller.rb index cd4c1a8d3..8dfebf026 100644 --- a/app/controllers/api/cors_controller.rb +++ b/app/controllers/api/cors_controller.rb @@ -5,7 +5,7 @@ module Api def cors_preflight_check set_access_control_headers - render text: '' + render plain: '' end def set_access_control_headers diff --git a/app/controllers/api/v1/auctions_controller.rb b/app/controllers/api/v1/auctions_controller.rb index bf92be930..de8e94442 100644 --- a/app/controllers/api/v1/auctions_controller.rb +++ b/app/controllers/api/v1/auctions_controller.rb @@ -30,6 +30,8 @@ module Api raise "Invalid status #{params[:status]}" end + auction.mark_deadline(params[:registration_deadline]) if params[:registration_deadline] + if auction.payment_not_received? || auction.domain_not_registered? update_whois_from_auction(Auction.pending(auction.domain)) else diff --git a/app/controllers/api/v1/base_controller.rb b/app/controllers/api/v1/base_controller.rb index c93160d9c..54930edf9 100644 --- a/app/controllers/api/v1/base_controller.rb +++ b/app/controllers/api/v1/base_controller.rb @@ -1,8 +1,8 @@ -require 'rails5_api_controller_backport' - module Api module V1 class BaseController < ActionController::API + rescue_from ActiveRecord::RecordNotFound, with: :not_found_error + private def authenticate @@ -10,6 +10,12 @@ module Api head :unauthorized unless ip_allowed end + def not_found_error + uuid = params['uuid'] + json = { error: 'Not Found', uuid: uuid, message: 'Record not found' } + render json: json, status: :not_found + end + def allowed_ips ENV['auction_api_allowed_ips'].split(',').map(&:strip) end diff --git a/app/controllers/api/v1/registrant/auth_controller.rb b/app/controllers/api/v1/registrant/auth_controller.rb index c1fe3fbf8..03dfa45f3 100644 --- a/app/controllers/api/v1/registrant/auth_controller.rb +++ b/app/controllers/api/v1/registrant/auth_controller.rb @@ -1,4 +1,3 @@ -require 'rails5_api_controller_backport' require 'auth_token/auth_token_creator' module Api @@ -16,7 +15,7 @@ module Api end def eid - user = RegistrantUser.find_or_create_by_api_data(eid_params) + user = RegistrantUser.find_or_create_by_api_data(eid_params.to_h) token = create_token(user) if token diff --git a/app/controllers/api/v1/registrant/base_controller.rb b/app/controllers/api/v1/registrant/base_controller.rb index 05702b4c9..16980be8b 100644 --- a/app/controllers/api/v1/registrant/base_controller.rb +++ b/app/controllers/api/v1/registrant/base_controller.rb @@ -1,4 +1,3 @@ -require 'rails5_api_controller_backport' require 'auth_token/auth_token_decryptor' module Api @@ -45,7 +44,7 @@ module Api # This controller does not inherit from ApplicationController, # so user_for_paper_trail method is not usable. def set_paper_trail_whodunnit - ::PaperTrail.whodunnit = current_registrant_user.id_role_username + ::PaperTrail.request.whodunnit = current_registrant_user.id_role_username end def show_not_found_error diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index dec34acbf..5a6b45668 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,9 +1,10 @@ class ApplicationController < ActionController::Base check_authorization unless: :devise_controller? + before_action :set_paper_trail_whodunnit # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. - protect_from_forgery with: :exception + protect_from_forgery with: :exception, prepend: true before_action do resource = controller_name.singularize.to_sym @@ -32,4 +33,4 @@ class ApplicationController < ActionController::Base def available_languages { en: 'English', et: 'Estonian' }.invert end -end \ No newline at end of file +end diff --git a/app/controllers/epp/base_controller.rb b/app/controllers/epp/base_controller.rb new file mode 100644 index 000000000..e9d58a4ed --- /dev/null +++ b/app/controllers/epp/base_controller.rb @@ -0,0 +1,406 @@ +module Epp + class BaseController < ActionController::Base + class AuthorizationError < StandardError; end + skip_before_action :verify_authenticity_token + check_authorization + layout false + + before_action :ensure_session_id_passed + before_action :generate_svtrid + before_action :latin_only + before_action :validate_against_schema + before_action :validate_request + before_action :update_epp_session, if: -> { signed_in? } + + around_action :wrap_exceptions + + helper_method :current_user + helper_method :resource + + rescue_from StandardError, with: :respond_with_command_failed_error + rescue_from AuthorizationError, with: :respond_with_authorization_error + rescue_from ActiveRecord::RecordNotFound, with: :respond_with_object_does_not_exist_error + before_action :set_paper_trail_whodunnit + + protected + + def respond_with_command_failed_error(exception) + epp_errors << { + code: '2400', + msg: 'Command failed', + } + handle_errors + log_exception(exception) + end + + def respond_with_object_does_not_exist_error + epp_errors << { + code: '2303', + msg: 'Object does not exist', + } + handle_errors + end + + def respond_with_authorization_error + epp_errors << { + code: '2201', + msg: 'Authorization error', + } + handle_errors + end + + private + + def wrap_exceptions + yield + rescue CanCan::AccessDenied + raise AuthorizationError + end + + def validate_against_schema + return if %w[hello error].include?(params[:action]) + schema.validate(params[:nokogiri_frame]).each do |error| + epp_errors << { + code: 2001, + msg: error + } + end + handle_errors and return if epp_errors.any? + end + + def schema + EPP_ALL_SCHEMA + end + + def generate_svtrid + @svTRID = "ccReg-#{format('%010d', rand(10 ** 10))}" + end + + def params_hash # TODO: THIS IS DEPRECATED AND WILL BE REMOVED IN FUTURE + @params_hash ||= Hash.from_xml(params[:frame]).with_indifferent_access + end + + def epp_session + EppSession.find_by(session_id: epp_session_id) + end + + def current_user + return unless signed_in? + epp_session.user + end + + # ERROR + RESPONSE HANDLING + def epp_errors + @errors ||= [] + end + + def handle_errors(obj = nil) + @errors ||= [] + + if obj + obj.construct_epp_errors + @errors += obj.errors[:epp_errors] + end + + if params[:parsed_frame].at_css('update') + @errors.each_with_index do |errors, index| + if errors[:code] == '2304' && + errors[:value].present? && + errors[:value][:val] == DomainStatus::SERVER_DELETE_PROHIBITED && + errors[:value][:obj] == 'status' + @errors[index][:value][:val] = DomainStatus::PENDING_UPDATE + end + end + end + + @errors.uniq! + + render_epp_response '/epp/error' + end + + def render_epp_response(*args) + @response = render_to_string(*args, formats: [:xml]) + render xml: @response + write_to_epp_log + end + + # VALIDATION + def latin_only + return true if params['frame'].blank? + if params['frame'].match?(/\A[\p{Latin}\p{Z}\p{P}\p{S}\p{Cc}\p{Cf}\w_\'\+\-\.\(\)\/]*\Z/i) + return true + end + + epp_errors << { + msg: 'Parameter value policy error. Allowed only Latin characters.', + code: '2306' + } + + handle_errors and return false + end + + # VALIDATION + def validate_request + validation_method = "validate_#{params[:action]}" + return unless respond_to?(validation_method, true) + send(validation_method) + + # validate legal document's type here because it may be in most of the requests + @prefix = nil + if element_count('extdata > legalDocument').positive? + requires_attribute('extdata > legalDocument', 'type', values: LegalDocument::TYPES, policy: true) + end + + handle_errors and return if epp_errors.any? + end + + # let's follow grape's validations: https://github.com/intridea/grape/#parameter-validation-and-coercion + + # Adds error to epp_errors if element is missing or blank + # Returns last element of selectors if it exists + # + # requires 'transfer' + # + # TODO: Add possibility to pass validations / options in the method + + def requires(*selectors) + options = selectors.extract_options! + allow_blank = options[:allow_blank] ||= false # allow_blank is false by default + + el, missing = nil, nil + selectors.each do |selector| + full_selector = [@prefix, selector].compact.join(' ') + attr = selector.split('>').last.strip.underscore + el = params[:parsed_frame].css(full_selector).first + + if allow_blank + missing = el.nil? + else + missing = el.present? ? el.text.blank? : true + end + epp_errors << { + code: '2003', + msg: I18n.t('errors.messages.required_parameter_missing', key: "#{full_selector} [#{attr}]") + } if missing + end + + missing ? false : el # return last selector if it was present + end + + # Adds error to epp_errors if element or attribute is missing or attribute attribute is not one + # of the values + # + # requires_attribute 'transfer', 'op', values: %(approve, query, reject) + + def requires_attribute(element_selector, attribute_selector, options) + element = requires(element_selector, allow_blank: options[:allow_blank]) + return unless element + + attribute = element[attribute_selector] + + unless attribute + epp_errors << { + code: '2003', + msg: I18n.t('errors.messages.required_parameter_missing', key: attribute_selector) + } + return + end + + return if options[:values].include?(attribute) + + if options[:policy] + epp_errors << { + code: '2306', + msg: I18n.t('attribute_is_invalid', attribute: attribute_selector) + } + else + epp_errors << { + code: '2004', + msg: I18n.t('parameter_value_range_error', key: attribute_selector) + } + end + end + + def optional_attribute(element_selector, attribute_selector, options) + full_selector = [@prefix, element_selector].compact.join(' ') + element = params[:parsed_frame].css(full_selector).first + return unless element + + attribute = element[attribute_selector] + return if (attribute && options[:values].include?(attribute)) || !attribute + + epp_errors << { + code: '2306', + msg: I18n.t('attribute_is_invalid', attribute: attribute_selector) + } + end + + def exactly_one_of(*selectors) + full_selectors = create_full_selectors(*selectors) + return if element_count(*full_selectors, use_prefix: false) == 1 + + epp_errors << { + code: '2306', + msg: I18n.t(:exactly_one_parameter_required, params: full_selectors.join(' OR ')) + } + end + + def mutually_exclusive(*selectors) + full_selectors = create_full_selectors(*selectors) + return if element_count(*full_selectors, use_prefix: false) <= 1 + + epp_errors << { + code: '2306', + msg: I18n.t(:mutally_exclusive_params, params: full_selectors.join(', ')) + } + end + + def optional(selector, *validations) + full_selector = [@prefix, selector].compact.join(' ') + el = params[:parsed_frame].css(full_selector).first + return unless el&.text.present? + value = el.text + + validations.each do |x| + validator = "#{x.first[0]}_validator".camelize.constantize + err = validator.validate_epp(selector.split(' ').last, value) + epp_errors << err if err + end + end + + # Returns how many elements were present in the request + # if use_prefix is true, @prefix will be prepended to selectors e.g create > create > name + # default is true + # + # @prefix = 'create > create >' + # element_count 'name', 'registrar', use_prefix: false + # => 2 + + def element_count(*selectors) + options = selectors.extract_options! + use_prefix = options[:use_prefix] != false # use_prefix is true by default + + present_count = 0 + selectors.each do |selector| + full_selector = use_prefix ? [@prefix, selector].compact.join(' ') : selector + el = params[:parsed_frame].css(full_selector).first + present_count += 1 if el && el.text.present? + end + present_count + end + + def create_full_selectors(*selectors) + selectors.map { |x| [@prefix, x].compact.join(' ') } + end + + def xml_attrs_present?(ph, attributes) # TODO: THIS IS DEPRECATED AND WILL BE REMOVED IN FUTURE + attributes.each do |x| + epp_errors << { + code: '2003', + msg: I18n.t('errors.messages.required_parameter_missing', key: x.last) + } unless has_attribute(ph, x) + end + epp_errors.empty? + end + + def has_attribute(ph, path) # TODO: THIS IS DEPRECATED AND WILL BE REMOVED IN FUTURE + path.reduce(ph) do |location, key| + location.respond_to?(:keys) ? location[key] : nil + end + end + + def write_to_epp_log + request_command = params[:command] || params[:action] # error receives :command, other methods receive :action + frame = params[:raw_frame] || params[:frame] + + # filter pw + if request_command == 'login' && frame.present? + frame.gsub!(/pw>.+<\//, 'pw>[FILTERED]]+)>([^<])+<\/eis:legalDocument>/, "[FILTERED]") if frame.present? + + ApiLog::EppLog.create({ + request: trimmed_request, + request_command: request_command, + request_successful: epp_errors.empty?, + request_object: resource ? "#{params[:epp_object_type]}: #{resource.class} - #{resource.id} - #{resource.name}" : params[:epp_object_type], + response: @response, + api_user_name: @api_user.try(:username) || current_user.try(:username) || 'api-public', + api_user_registrar: @api_user.try(:registrar).try(:to_s) || current_user.try(:registrar).try(:to_s), + ip: request.ip, + uuid: request.uuid + }) + end + + def resource + name = self.class.to_s.sub("Epp::", "").sub("Controller", "").underscore.singularize + instance_variable_get("@#{name}") + end + + def signed_in? + epp_session + end + + def epp_session_id + cookies[:session] # Passed by mod_epp https://github.com/mod-epp/mod-epp#requestscript-interface + end + + def ensure_session_id_passed + raise 'EPP session id is empty' unless epp_session_id.present? + end + + def update_epp_session + iptables_counter_update + + if session_timeout_reached? + @api_user = current_user # cache current_user for logging + epp_session.destroy + + epp_errors << { + msg: t('session_timeout'), + code: '2201' + } + + handle_errors and return + else + epp_session.update_column(:updated_at, Time.zone.now) + end + end + + def session_timeout_reached? + timeout = 5.minutes + epp_session.updated_at < (Time.zone.now - timeout) + end + + def iptables_counter_update + return if ENV['iptables_counter_enabled'].blank? && ENV['iptables_counter_enabled'] != 'true' + return if current_user.blank? + counter_update(current_user.registrar_code, ENV['iptables_server_ip']) + end + + def counter_update(registrar_code, ip) + counter_proc = "/proc/net/xt_recent/#{registrar_code}" + + begin + File.open(counter_proc, 'a') do |f| + f.puts "+#{ip}" + end + rescue Errno::ENOENT => e + logger.error "IPTABLES COUNTER UPDATE: cannot open #{counter_proc}: #{e}" + rescue Errno::EACCES => e + logger.error "IPTABLES COUNTER UPDATE: no permission #{counter_proc}: #{e}" + rescue IOError => e + logger.error "IPTABLES COUNTER UPDATE: cannot write #{ip} to #{counter_proc}: #{e}" + end + end + + def log_exception(exception) + logger.error(([exception.message] + exception.backtrace).join($INPUT_RECORD_SEPARATOR)) + notify_airbrake(exception) + end + + def user_for_paper_trail + current_user ? current_user.id_role_username : 'anonymous' + end + end +end diff --git a/app/controllers/epp/contacts_controller.rb b/app/controllers/epp/contacts_controller.rb index 7f28961f6..df9755af6 100644 --- a/app/controllers/epp/contacts_controller.rb +++ b/app/controllers/epp/contacts_controller.rb @@ -1,210 +1,214 @@ -class Epp::ContactsController < EppController - before_action :find_contact, only: [:info, :update, :delete] - before_action :find_password, only: [:info, :update, :delete] - helper_method :address_processing? +require 'deserializers/xml/contact_update' - def info - authorize! :info, @contact, @password - render_epp_response 'epp/contacts/info' - end +module Epp + class ContactsController < BaseController + before_action :find_contact, only: [:info, :update, :delete] + before_action :find_password, only: [:info, :update, :delete] + helper_method :address_processing? - def check - authorize! :check, Epp::Contact + def info + authorize! :info, @contact, @password + render_epp_response 'epp/contacts/info' + end - ids = params[:parsed_frame].css('id').map(&:text) - @results = Epp::Contact.check_availability(ids) - render_epp_response '/epp/contacts/check' - end + def check + authorize! :check, Epp::Contact - def create - authorize! :create, Epp::Contact - frame = params[:parsed_frame] - @contact = Epp::Contact.new(frame, current_user.registrar) + ids = params[:parsed_frame].css('id').map(&:text) + @results = Epp::Contact.check_availability(ids) + render_epp_response '/epp/contacts/check' + end - @contact.add_legal_file_to_new(frame) - @contact.generate_code + def create + authorize! :create, Epp::Contact + frame = params[:parsed_frame] + @contact = Epp::Contact.new(frame, current_user.registrar) - if @contact.save - if !address_processing? && address_given? - @response_code = 1100 - @response_description = t('epp.contacts.completed_without_address') + @contact.add_legal_file_to_new(frame) + @contact.generate_code + + if @contact.save + if !address_processing? && address_given? + @response_code = 1100 + @response_description = t('epp.contacts.completed_without_address') + else + @response_code = 1000 + @response_description = t('epp.contacts.completed') + end + + render_epp_response '/epp/contacts/save' else - @response_code = 1000 - @response_description = t('epp.contacts.completed') + handle_errors(@contact) + end + end + + def update + authorize! :update, @contact, @password + + collected_data = ::Deserializers::Xml::ContactUpdate.new(params[:parsed_frame]) + action = Actions::ContactUpdate.new(@contact, + collected_data.contact, + collected_data.legal_document, + collected_data.ident, + current_user) + + if action.call + if !address_processing? && address_given? + @response_code = 1100 + @response_description = t('epp.contacts.completed_without_address') + else + @response_code = 1000 + @response_description = t('epp.contacts.completed') + end + + render_epp_response 'epp/contacts/save' + else + handle_errors(@contact) + end + end + + def delete + authorize! :delete, @contact, @password + + if @contact.destroy_and_clean(params[:parsed_frame]) + render_epp_response '/epp/contacts/delete' + else + handle_errors(@contact) + end + end + + def renew + authorize! :renew, Epp::Contact + epp_errors << { code: '2101', msg: t(:'errors.messages.unimplemented_command') } + handle_errors + end + + def transfer + authorize! :transfer, Epp::Contact + epp_errors << { code: '2101', msg: t(:'errors.messages.unimplemented_command') } + handle_errors + end + + private + + def find_password + @password = params[:parsed_frame].css('authInfo pw').text + end + + def find_contact + code = params[:parsed_frame].css('id').text.strip.upcase + @contact = Epp::Contact.find_by!(code: code) + end + + # + # Validations + # + def validate_info + @prefix = 'info > info >' + requires 'id' + end + + def validate_check + @prefix = 'check > check >' + requires 'id' + end + + def validate_create + @prefix = 'create > create >' + + required_attributes = [ + 'postalInfo > name', + 'voice', + 'email' + ] + + address_attributes = [ + 'postalInfo > addr > street', + 'postalInfo > addr > city', + 'postalInfo > addr > pc', + 'postalInfo > addr > cc', + ] + + required_attributes.concat(address_attributes) if address_processing? + + requires(*required_attributes) + ident = params[:parsed_frame].css('ident') + + if ident.present? && ident.attr('type').blank? + epp_errors << { + code: '2003', + msg: I18n.t('errors.messages.required_ident_attribute_missing', key: 'type') + } end - render_epp_response '/epp/contacts/save' - else - handle_errors(@contact) - end - end - - def update - authorize! :update, @contact, @password - - frame = params[:parsed_frame] - - if @contact.update_attributes(frame, current_user) - if !address_processing? && address_given? - @response_code = 1100 - @response_description = t('epp.contacts.completed_without_address') - else - @response_code = 1000 - @response_description = t('epp.contacts.completed') + if ident.present? && ident.text != 'birthday' && ident.attr('cc').blank? + epp_errors << { + code: '2003', + msg: I18n.t('errors.messages.required_ident_attribute_missing', key: 'cc') + } end - - render_epp_response 'epp/contacts/save' - else - handle_errors(@contact) - end - end - - def delete - authorize! :delete, @contact, @password - - if @contact.destroy_and_clean(params[:parsed_frame]) - render_epp_response '/epp/contacts/delete' - else - handle_errors(@contact) - end - end - - def renew - authorize! :renew, Epp::Contact - epp_errors << { code: '2101', msg: t(:'errors.messages.unimplemented_command') } - handle_errors - end - - private - - def find_password - @password = params[:parsed_frame].css('authInfo pw').text - end - - def find_contact - code = params[:parsed_frame].css('id').text.strip.upcase - - @contact = Epp::Contact.find_by_epp_code(code) - - if @contact.blank? - epp_errors << { - code: '2303', - msg: t('errors.messages.epp_obj_does_not_exist'), - value: { obj: 'id', val: code } - } - fail CanCan::AccessDenied - end - @contact - end - - # - # Validations - # - def validate_info - @prefix = 'info > info >' - requires 'id' - end - - def validate_check - @prefix = 'check > check >' - requires 'id' - end - - def validate_create - @prefix = 'create > create >' - - required_attributes = [ - 'postalInfo > name', - 'voice', - 'email' - ] - - address_attributes = [ - 'postalInfo > addr > street', - 'postalInfo > addr > city', - 'postalInfo > addr > pc', - 'postalInfo > addr > cc', - ] - - required_attributes.concat(address_attributes) if address_processing? - - requires(*required_attributes) - ident = params[:parsed_frame].css('ident') - - if ident.present? && ident.attr('type').blank? - epp_errors << { - code: '2003', - msg: I18n.t('errors.messages.required_ident_attribute_missing', key: 'type') - } - end - - if ident.present? && ident.text != 'birthday' && ident.attr('cc').blank? - epp_errors << { - code: '2003', - msg: I18n.t('errors.messages.required_ident_attribute_missing', key: 'cc') - } - end - # if ident.present? && ident.attr('cc').blank? + # if ident.present? && ident.attr('cc').blank? # epp_errors << { - # code: '2003', - # msg: I18n.t('errors.messages.required_ident_attribute_missing', key: 'cc') + # code: '2003', + # msg: I18n.t('errors.messages.required_ident_attribute_missing', key: 'cc') # } - # end - contact_org_disabled - fax_disabled - status_editing_disabled - @prefix = nil - requires 'extension > extdata > ident' - end + # end + contact_org_disabled + fax_disabled + status_editing_disabled + @prefix = nil + requires 'extension > extdata > ident' + end - def validate_update - @prefix = 'update > update >' - contact_org_disabled - fax_disabled - status_editing_disabled - requires 'id' - @prefix = nil - end + def validate_update + @prefix = 'update > update >' + contact_org_disabled + fax_disabled + status_editing_disabled + requires 'id' + @prefix = nil + end - def validate_delete - @prefix = 'delete > delete >' - requires 'id' - @prefix = nil - end + def validate_delete + @prefix = 'delete > delete >' + requires 'id' + @prefix = nil + end - def contact_org_disabled - return true if ENV['contact_org_enabled'] == 'true' - return true if params[:parsed_frame].css('postalInfo org').text.blank? + def contact_org_disabled + return true if ENV['contact_org_enabled'] == 'true' + return true if params[:parsed_frame].css('postalInfo org').text.blank? - epp_errors << { - code: '2306', - msg: "#{I18n.t(:contact_org_error)}: postalInfo > org [org]" - } - end + epp_errors << { + code: '2306', + msg: "#{I18n.t(:contact_org_error)}: postalInfo > org [org]" + } + end - def fax_disabled - return true if ENV['fax_enabled'] == 'true' - return true if params[:parsed_frame].css('fax').text.blank? - epp_errors << { - code: '2306', - msg: "#{I18n.t(:contact_fax_error)}: fax [fax]" - } - end + def fax_disabled + return true if ENV['fax_enabled'] == 'true' + return true if params[:parsed_frame].css('fax').text.blank? + epp_errors << { + code: '2306', + msg: "#{I18n.t(:contact_fax_error)}: fax [fax]" + } + end - def status_editing_disabled - return true if Setting.client_status_editing_enabled - return true if params[:parsed_frame].css('status').empty? - epp_errors << { - code: '2306', - msg: "#{I18n.t(:client_side_status_editing_error)}: status [status]" - } - end + def status_editing_disabled + return true if Setting.client_status_editing_enabled + return true if params[:parsed_frame].css('status').empty? + epp_errors << { + code: '2306', + msg: "#{I18n.t(:client_side_status_editing_error)}: status [status]" + } + end - def address_given? - params[:parsed_frame].css('postalInfo addr').size != 0 - end + def address_given? + params[:parsed_frame].css('postalInfo addr').size != 0 + end - def address_processing? - Contact.address_processing? + def address_processing? + Contact.address_processing? + end end end diff --git a/app/controllers/epp/domains_controller.rb b/app/controllers/epp/domains_controller.rb index ecee7ae9d..d9a8b2b5d 100644 --- a/app/controllers/epp/domains_controller.rb +++ b/app/controllers/epp/domains_controller.rb @@ -1,92 +1,122 @@ -class Epp::DomainsController < EppController - before_action :find_domain, only: %i[info renew update transfer delete] - before_action :find_password, only: %i[info update transfer delete] +module Epp + class DomainsController < BaseController + before_action :find_domain, only: %i[info renew update transfer delete] + before_action :find_password, only: %i[info update transfer delete] + before_action :set_paper_trail_whodunnit - def info - authorize! :info, @domain, @password + def info + authorize! :info, @domain - @hosts = params[:parsed_frame].css('name').first['hosts'] || 'all' + @hosts = params[:parsed_frame].css('name').first['hosts'] || 'all' - case @hosts - when 'del' - @nameservers = @domain.delegated_nameservers.sort - when 'sub' - @nameservers = @domain.subordinate_nameservers.sort - when 'all' - @nameservers = @domain.nameservers.sort + sponsoring_registrar = (@domain.registrar == current_user.registrar) + correct_transfer_code_provided = (@domain.transfer_code == @password) + @reveal_full_details = (sponsoring_registrar || correct_transfer_code_provided) + + case @hosts + when 'del' + @nameservers = @domain.delegated_nameservers.sort + when 'sub' + @nameservers = @domain.subordinate_nameservers.sort + when 'all' + @nameservers = @domain.nameservers.sort + end + + render_epp_response '/epp/domains/info' end - render_epp_response '/epp/domains/info' - end + def create + authorize! :create, Epp::Domain - def create - authorize! :create, Epp::Domain + if Domain.release_to_auction + request_domain_name = params[:parsed_frame].css('name').text.strip.downcase + domain_name = DNS::DomainName.new(SimpleIDN.to_unicode(request_domain_name)) - if Domain.release_to_auction - request_domain_name = params[:parsed_frame].css('name').text.strip.downcase - domain_name = DNS::DomainName.new(SimpleIDN.to_unicode(request_domain_name)) + if domain_name.at_auction? + epp_errors << { + code: '2306', + msg: 'Parameter value policy error: domain is at auction', + } + handle_errors + return + elsif domain_name.awaiting_payment? + epp_errors << { + code: '2003', + msg: 'Required parameter missing; reserved>pw element required for reserved domains', + } + handle_errors + return + elsif domain_name.pending_registration? + registration_code = params[:parsed_frame].css('reserved > pw').text - if domain_name.at_auction? - throw :epp_error, - code: '2306', - msg: 'Parameter value policy error: domain is at auction' - elsif domain_name.awaiting_payment? - throw :epp_error, + if registration_code.empty? + epp_errors << { code: '2003', - msg: 'Required parameter missing; reserved>pw element required for reserved domains' - elsif domain_name.pending_registration? - registration_code = params[:parsed_frame].css('reserved > pw').text + msg: 'Required parameter missing; reserved>pw element is required', + } + handle_errors + return + end - if registration_code.empty? - throw :epp_error, - code: '2003', - msg: 'Required parameter missing; reserved>pw element is required' + unless domain_name.available_with_code?(registration_code) + epp_errors << { + code: '2202', + msg: 'Invalid authorization information; invalid reserved>pw value', + } + handle_errors + return + end end + end - unless domain_name.available_with_code?(registration_code) - throw :epp_error, - code: '2202', - msg: 'Invalid authorization information; invalid reserved>pw value' + @domain = Epp::Domain.new_from_epp(params[:parsed_frame], current_user) + handle_errors(@domain) and return if @domain.errors.any? + @domain.valid? + @domain.errors.delete(:name_dirty) if @domain.errors[:puny_label].any? + handle_errors(@domain) and return if @domain.errors.any? + handle_errors and return unless balance_ok?('create') # loads pricelist in this method + + ActiveRecord::Base.transaction do + @domain.add_legal_file_to_new(params[:parsed_frame]) + + if @domain.save # TODO: Maybe use validate: false here because we have already validated the domain? + current_user.registrar.debit!({ + sum: @domain_pricelist.price.amount, + description: "#{I18n.t('create')} #{@domain.name}", + activity_type: AccountActivity::CREATE, + price: @domain_pricelist + }) + + if Domain.release_to_auction && domain_name.pending_registration? + active_auction = Auction.find_by(domain: domain_name.to_s, + status: Auction.statuses[:payment_received]) + active_auction.domain_registered! + end + Dispute.close_by_domain(@domain.name) + render_epp_response '/epp/domains/create' + else + handle_errors(@domain) end end end - @domain = Epp::Domain.new_from_epp(params[:parsed_frame], current_user) - handle_errors(@domain) and return if @domain.errors.any? - @domain.valid? - @domain.errors.delete(:name_dirty) if @domain.errors[:puny_label].any? - handle_errors(@domain) and return if @domain.errors.any? - handle_errors and return unless balance_ok?('create') # loads pricelist in this method + def update + authorize! :update, @domain, @password - ActiveRecord::Base.transaction do - @domain.add_legal_file_to_new(params[:parsed_frame]) + updated = @domain.update(params[:parsed_frame], current_user) + (handle_errors(@domain) && return) unless updated - if @domain.save # TODO: Maybe use validate: false here because we have already validated the domain? - current_user.registrar.debit!({ - sum: @domain_pricelist.price.amount, - description: "#{I18n.t('create')} #{@domain.name}", - activity_type: AccountActivity::CREATE, - price: @domain_pricelist - }) - - if Domain.release_to_auction && domain_name.pending_registration? - active_auction = Auction.find_by(domain: domain_name.to_s, - status: Auction.statuses[:payment_received]) - active_auction.domain_registered! - end - - render_epp_response '/epp/domains/create' - else - handle_errors(@domain) - end + pending = @domain.epp_pending_update.present? + render_epp_response "/epp/domains/success#{'_pending' if pending}" end - end - def update - authorize! :update, @domain, @password - begin - if @domain.update(params[:parsed_frame], current_user) - if @domain.epp_pending_update.present? + def delete + authorize! :delete, @domain, @password + + (handle_errors(@domain) && return) unless @domain.can_be_deleted? + + if @domain.epp_destroy(params[:parsed_frame], current_user.id) + if @domain.epp_pending_delete.present? render_epp_response '/epp/domains/success_pending' else render_epp_response '/epp/domains/success' @@ -94,227 +124,219 @@ class Epp::DomainsController < EppController else handle_errors(@domain) end - rescue => e - if @domain.errors.any? - handle_errors(@domain) - else - throw e - end end - end - def delete - authorize! :delete, @domain, @password - # all includes for bullet - @domain = Epp::Domain.where(id: @domain.id).includes(nameservers: :versions).first + def check + authorize! :check, Epp::Domain - handle_errors(@domain) and return unless @domain.can_be_deleted? - - if @domain.epp_destroy(params[:parsed_frame], current_user.id) - if @domain.epp_pending_delete.present? - render_epp_response '/epp/domains/success_pending' - else - render_epp_response '/epp/domains/success' - end - else - handle_errors(@domain) + domain_names = params[:parsed_frame].css('name').map(&:text) + @domains = Epp::Domain.check_availability(domain_names) + render_epp_response '/epp/domains/check' end - end - def check - authorize! :check, Epp::Domain + def renew + authorize! :renew, @domain - domain_names = params[:parsed_frame].css('name').map(&:text) - @domains = Epp::Domain.check_availability(domain_names) - render_epp_response '/epp/domains/check' - end + period_element = params[:parsed_frame].css('period').text + period = (period_element.to_i == 0) ? 1 : period_element.to_i + period_unit = Epp::Domain.parse_period_unit_from_frame(params[:parsed_frame]) || 'y' - def renew - authorize! :renew, @domain + balance_ok?('renew', period, period_unit) # loading pricelist - period_element = params[:parsed_frame].css('period').text - period = (period_element.to_i == 0) ? 1 : period_element.to_i - period_unit = Epp::Domain.parse_period_unit_from_frame(params[:parsed_frame]) || 'y' + begin + ActiveRecord::Base.transaction(isolation: :serializable) do + @domain.reload - balance_ok?('renew', period, period_unit) # loading pricelist + success = @domain.renew( + params[:parsed_frame].css('curExpDate').text, + period, period_unit + ) - begin - ActiveRecord::Base.transaction(isolation: :serializable) do - @domain.reload + if success + unless balance_ok?('renew', period, period_unit) + handle_errors + fail ActiveRecord::Rollback + end - success = @domain.renew( - params[:parsed_frame].css('curExpDate').text, - period, period_unit - ) + current_user.registrar.debit!({ + sum: @domain_pricelist.price.amount, + description: "#{I18n.t('renew')} #{@domain.name}", + activity_type: AccountActivity::RENEW, + price: @domain_pricelist + }) - if success - unless balance_ok?('renew', period, period_unit) - handle_errors - fail ActiveRecord::Rollback + render_epp_response '/epp/domains/renew' + else + handle_errors(@domain) end - - current_user.registrar.debit!({ - sum: @domain_pricelist.price.amount, - description: "#{I18n.t('renew')} #{@domain.name}", - activity_type: AccountActivity::RENEW, - price: @domain_pricelist - }) - - render_epp_response '/epp/domains/renew' - else - handle_errors(@domain) end + rescue ActiveRecord::StatementInvalid => e + sleep rand / 100 + retry end - rescue ActiveRecord::StatementInvalid => e - sleep rand / 100 - retry - end - end - - def transfer - authorize! :transfer, @domain, @password - action = params[:parsed_frame].css('transfer').first[:op] - - if @domain.non_transferable? - throw :epp_error, { - code: '2304', - msg: I18n.t(:object_status_prohibits_operation) - } end - @domain_transfer = @domain.transfer(params[:parsed_frame], action, current_user) + def transfer + authorize! :transfer, @domain + action = params[:parsed_frame].css('transfer').first[:op] - if @domain_transfer - render_epp_response '/epp/domains/transfer' - else - epp_errors << { - code: '2303', - msg: I18n.t('no_transfers_found') - } - handle_errors - end - end - - private - - def validate_info - @prefix = 'info > info >' - requires('name') - optional_attribute 'name', 'hosts', values: %(all, sub, del, none) - end - - def validate_create - if Domain.nameserver_required? - @prefix = 'create > create >' - requires 'name', 'ns', 'registrant', 'ns > hostAttr' - end - - @prefix = 'extension > create >' - mutually_exclusive 'keyData', 'dsData' - - @prefix = nil - requires 'extension > extdata > legalDocument' - - optional_attribute 'period', 'unit', values: %w(d m y) - - status_editing_disabled - end - - def validate_update - if element_count('update > chg > registrant') > 0 - requires 'extension > extdata > legalDocument' - end - - @prefix = 'update > update >' - requires 'name' - - status_editing_disabled - end - - def validate_delete - requires 'extension > extdata > legalDocument' - - @prefix = 'delete > delete >' - requires 'name' - end - - def validate_check - @prefix = 'check > check >' - requires('name') - end - - def validate_renew - @prefix = 'renew > renew >' - requires 'name', 'curExpDate' - - optional_attribute 'period', 'unit', values: %w(d m y) - end - - def validate_transfer - # period element is disabled for now - if params[:parsed_frame].css('period').any? - epp_errors << { - code: '2307', - msg: I18n.t(:unimplemented_object_service), - value: { obj: 'period' } - } - end - - requires 'transfer > transfer' - - @prefix = 'transfer > transfer >' - requires 'name' - - @prefix = nil - requires_attribute 'transfer', 'op', values: %(approve, query, reject, request, cancel) - end - - def find_domain - domain_name = params[:parsed_frame].css('name').text.strip.downcase - @domain = Epp::Domain.find_by_idn domain_name - - unless @domain - epp_errors << { - code: '2303', - msg: I18n.t('errors.messages.epp_domain_not_found'), - value: { obj: 'name', val: domain_name } - } - fail CanCan::AccessDenied - end - - @domain - end - - def find_password - @password = params[:parsed_frame].css('authInfo pw').text - end - - def status_editing_disabled - return true if Setting.client_status_editing_enabled - return true if params[:parsed_frame].css('status').empty? - epp_errors << { - code: '2306', - msg: "#{I18n.t(:client_side_status_editing_error)}: status [status]" - } - end - - def balance_ok?(operation, period = nil, unit = nil) - @domain_pricelist = @domain.pricelist(operation, period.try(:to_i), unit) - if @domain_pricelist.try(:price) # checking if price list is not found - if current_user.registrar.balance < @domain_pricelist.price.amount + if @domain.non_transferable? epp_errors << { + code: '2304', + msg: I18n.t(:object_status_prohibits_operation), + } + handle_errors + return + end + + provided_transfer_code = params[:parsed_frame].css('authInfo pw').text + wrong_transfer_code = provided_transfer_code != @domain.transfer_code + + if wrong_transfer_code + epp_errors << { + code: '2202', + msg: 'Invalid authorization information', + } + handle_errors + return + end + + @domain_transfer = @domain.transfer(params[:parsed_frame], action, current_user) + + if @domain.errors[:epp_errors].any? + handle_errors(@domain) + return + end + + if @domain_transfer + render_epp_response '/epp/domains/transfer' + else + epp_errors << { + code: '2303', + msg: I18n.t('no_transfers_found') + } + handle_errors + end + end + + private + + def validate_info + @prefix = 'info > info >' + requires('name') + optional_attribute 'name', 'hosts', values: %(all, sub, del, none) + end + + def validate_create + if Domain.nameserver_required? + @prefix = 'create > create >' + requires 'name', 'ns', 'registrant', 'ns > hostAttr' + end + + @prefix = 'extension > create >' + mutually_exclusive 'keyData', 'dsData' + + @prefix = nil + requires 'extension > extdata > legalDocument' if current_user.legaldoc_mandatory? + + optional_attribute 'period', 'unit', values: %w(d m y) + + status_editing_disabled + end + + def validate_update + if element_count('update > chg > registrant') > 0 + requires 'extension > extdata > legalDocument' if current_user.legaldoc_mandatory? + end + + @prefix = 'update > update >' + requires 'name' + + status_editing_disabled + end + + def validate_delete + @prefix = 'delete > delete >' + requires 'name' + end + + def validate_check + @prefix = 'check > check >' + requires('name') + end + + def validate_renew + @prefix = 'renew > renew >' + requires 'name', 'curExpDate' + + optional_attribute 'period', 'unit', values: %w(d m y) + end + + def validate_transfer + # period element is disabled for now + if params[:parsed_frame].css('period').any? + epp_errors << { + code: '2307', + msg: I18n.t(:unimplemented_object_service), + value: { obj: 'period' } + } + end + + requires 'transfer > transfer' + + @prefix = 'transfer > transfer >' + requires 'name' + + @prefix = nil + requires_attribute 'transfer', 'op', values: %(approve, query, reject, request, cancel) + end + + def find_domain + domain_name = params[:parsed_frame].css('name').text.strip.downcase + + domain = Epp::Domain.find_by_idn(domain_name) + raise ActiveRecord::RecordNotFound unless domain + + @domain = domain + end + + def find_password + @password = params[:parsed_frame].css('authInfo pw').text + end + + def status_editing_disabled + return true if Setting.client_status_editing_enabled + return true if check_client_hold + return true if params[:parsed_frame].css('status').empty? + epp_errors << { + code: '2306', + msg: "#{I18n.t(:client_side_status_editing_error)}: status [status]" + } + end + + def check_client_hold + statuses = params[:parsed_frame].css('status').map { |element| element['s'] } + statuses == [::DomainStatus::CLIENT_HOLD] + end + + def balance_ok?(operation, period = nil, unit = nil) + @domain_pricelist = @domain.pricelist(operation, period.try(:to_i), unit) + if @domain_pricelist.try(:price) # checking if price list is not found + if current_user.registrar.balance < @domain_pricelist.price.amount + epp_errors << { code: '2104', msg: I18n.t('billing_failure_credit_balance_low') + } + return false + end + else + epp_errors << { + code: '2104', + msg: I18n.t(:active_price_missing_for_this_operation) } return false end - else - epp_errors << { - code: '2104', - msg: I18n.t(:active_price_missing_for_this_operation) - } - return false + true end - true end end diff --git a/app/controllers/epp/errors_controller.rb b/app/controllers/epp/errors_controller.rb index 05618f5f7..e4b179464 100644 --- a/app/controllers/epp/errors_controller.rb +++ b/app/controllers/epp/errors_controller.rb @@ -1,13 +1,10 @@ -class Epp::ErrorsController < EppController - skip_authorization_check +module Epp + class ErrorsController < BaseController + skip_authorization_check - def error - epp_errors << { code: params[:code], msg: params[:msg] } - render_epp_response '/epp/error' - end - - def not_found - epp_errors << { code: 2400, msg: t(:could_not_determine_object_type_check_xml_format_and_namespaces) } - render_epp_response '/epp/error' + def error + epp_errors << { code: params[:code], msg: params[:msg] } + render_epp_response '/epp/error' + end end end diff --git a/app/controllers/epp/keyrelays_controller.rb b/app/controllers/epp/keyrelays_controller.rb deleted file mode 100644 index c4d7ef395..000000000 --- a/app/controllers/epp/keyrelays_controller.rb +++ /dev/null @@ -1,61 +0,0 @@ -class Epp::KeyrelaysController < EppController - skip_authorization_check # TODO: move authorization under ability - - def keyrelay - # keyrelay temp turned off - @domain = find_domain - - handle_errors(@domain) and return unless @domain - handle_errors(@domain) and return unless @domain.authenticate(params[:parsed_frame].css('pw').text) - handle_errors(@domain) and return unless @domain.keyrelay(params[:parsed_frame], current_user.registrar) - - render_epp_response '/epp/shared/success' - end - - private - - def validate_keyrelay - @prefix = 'keyrelay >' - - requires( - 'name', - 'keyData', 'keyData > pubKey', 'keyData > flags', 'keyData > protocol', 'keyData > alg', - 'authInfo', 'authInfo > pw' - ) - - optional 'expiry > relative', duration_iso8601: true - optional 'expiry > absolute', date_time_iso8601: true - - exactly_one_of 'expiry > relative', 'expiry > absolute' - end - - def find_domain - domain_name = params[:parsed_frame].css('name').text.strip.downcase - - # keyrelay temp turned off - epp_errors << { - code: '2307', - msg: I18n.t(:unimplemented_object_service), - value: { obj: 'name', val: domain_name } - } - nil - # end of keyrelay temp turned off - - # domain = Epp::Domain.includes(:registrant).find_by(name: domain_name) - - # unless domain - # epp_errors << { - # code: '2303', - # msg: I18n.t('errors.messages.epp_domain_not_found'), - # value: { obj: 'name', val: domain_name } - # } - # return nil - # end - - # domain - end - - def resource - @domain - end -end diff --git a/app/controllers/epp/polls_controller.rb b/app/controllers/epp/polls_controller.rb index 57961eb82..a7568b6bd 100644 --- a/app/controllers/epp/polls_controller.rb +++ b/app/controllers/epp/polls_controller.rb @@ -1,61 +1,59 @@ -class Epp::PollsController < EppController - skip_authorization_check # TODO: move authorization under ability +module Epp + class PollsController < BaseController + skip_authorization_check # TODO: move authorization under ability - def poll - req_poll if params[:parsed_frame].css('poll').first['op'] == 'req' - ack_poll if params[:parsed_frame].css('poll').first['op'] == 'ack' - end - - private - - def req_poll - @notification = current_user.unread_notifications.order('created_at DESC').take - - render_epp_response 'epp/poll/poll_no_messages' and return unless @notification - if @notification.attached_obj_type && @notification.attached_obj_id - begin - @object = Object.const_get(@notification.attached_obj_type).find(@notification.attached_obj_id) - rescue => problem - # the data model might be inconsistent; or ... - # this could happen if the registrar does not dequeue messages, and then the domain was deleted - - # SELECT messages.id, domains.name, messages.body FROM messages LEFT OUTER - # JOIN domains ON attached_obj_id::INTEGER = domains.id - # WHERE attached_obj_type = 'Epp::Domain' AND name IS NULL; - - Rails.logger.error 'orphan message, error ignored: ' + problem.to_s - # now we should dequeue or delete the messages avoid duplicate log alarms - end + def poll + req_poll if params[:parsed_frame].css('poll').first['op'] == 'req' + ack_poll if params[:parsed_frame].css('poll').first['op'] == 'ack' end - if @notification.attached_obj_type == 'Keyrelay' - render_epp_response 'epp/poll/poll_keyrelay' - else + private + + def req_poll + @notification = current_user.unread_notifications.order('created_at DESC').take + + render_epp_response 'epp/poll/poll_no_messages' and return unless @notification + if @notification.attached_obj_type && @notification.attached_obj_id + begin + @object = Object.const_get(@notification.attached_obj_type).find(@notification.attached_obj_id) + rescue => problem + # the data model might be inconsistent; or ... + # this could happen if the registrar does not dequeue messages, and then the domain was deleted + + # SELECT messages.id, domains.name, messages.body FROM messages LEFT OUTER + # JOIN domains ON attached_obj_id::INTEGER = domains.id + # WHERE attached_obj_type = 'Epp::Domain' AND name IS NULL; + + Rails.logger.error 'orphan message, error ignored: ' + problem.to_s + # now we should dequeue or delete the messages avoid duplicate log alarms + end + end + render_epp_response 'epp/poll/poll_req' end - end - def ack_poll - @notification = current_user.unread_notifications.find_by(id: params[:parsed_frame].css('poll').first['msgID']) + def ack_poll + @notification = current_user.unread_notifications.find_by(id: params[:parsed_frame].css('poll').first['msgID']) - unless @notification - epp_errors << { - code: '2303', - msg: I18n.t('message_was_not_found'), - value: { obj: 'msgID', val: params[:parsed_frame].css('poll').first['msgID'] } - } - handle_errors and return + unless @notification + epp_errors << { + code: '2303', + msg: I18n.t('message_was_not_found'), + value: { obj: 'msgID', val: params[:parsed_frame].css('poll').first['msgID'] } + } + handle_errors and return + end + + handle_errors(@notification) and return unless @notification.mark_as_read + render_epp_response 'epp/poll/poll_ack' end - handle_errors(@notification) and return unless @notification.mark_as_read - render_epp_response 'epp/poll/poll_ack' - end + def validate_poll + requires_attribute 'poll', 'op', values: %(ack req), allow_blank: true + end - def validate_poll - requires_attribute 'poll', 'op', values: %(ack req), allow_blank: true - end - - def resource - @notification + def resource + @notification + end end end diff --git a/app/controllers/epp/sessions_controller.rb b/app/controllers/epp/sessions_controller.rb index 05bbba9a8..b1c7fbbfb 100644 --- a/app/controllers/epp/sessions_controller.rb +++ b/app/controllers/epp/sessions_controller.rb @@ -1,138 +1,144 @@ -class Epp::SessionsController < EppController - skip_authorization_check only: [:hello, :login, :logout] +module Epp + class SessionsController < BaseController + skip_authorization_check only: [:hello, :login, :logout] + before_action :set_paper_trail_whodunnit - def hello - render_epp_response('greeting') - end - - def login - success = true - @api_user = ApiUser.find_by(login_params) - - webclient_request = ENV['webclient_ips'].split(',').map(&:strip).include?(request.ip) - if webclient_request && !Rails.env.test? && !Rails.env.development? - client_md5 = Certificate.parse_md_from_string(request.env['HTTP_SSL_CLIENT_CERT']) - server_md5 = Certificate.parse_md_from_string(File.read(ENV['cert_path'])) - if client_md5 != server_md5 - epp_errors << { - msg: 'Authentication error; server closing connection (certificate is not valid)', - code: '2501' - } - - success = false - end + def hello + render_epp_response('greeting') end - if !Rails.env.development? && (!webclient_request && @api_user) - unless @api_user.api_pki_ok?(request.env['HTTP_SSL_CLIENT_CERT'], request.env['HTTP_SSL_CLIENT_S_DN_CN']) - epp_errors << { - msg: 'Authentication error; server closing connection (certificate is not valid)', - code: '2501' - } + def login + success = true + @api_user = ApiUser.find_by(login_params) - success = false - end - end + webclient_request = ENV['webclient_ips'].split(',').map(&:strip).include?(request.ip) + if webclient_request && !Rails.env.test? && !Rails.env.development? + client_md5 = Certificate.parse_md_from_string(request.env['HTTP_SSL_CLIENT_CERT']) + if ENV['cert_path'].blank? + raise 'webclient cert (cert_path) missing, registrar (r)epp disabled' + end - if success && !@api_user - epp_errors << { - msg: 'Authentication error; server closing connection (API user not found)', - code: '2501' - } + server_md5 = Certificate.parse_md_from_string(File.read(ENV['cert_path'])) + if client_md5 != server_md5 + epp_errors << { + msg: 'Authentication error; server closing connection (certificate is not valid)', + code: '2501' + } - success = false - end - - if success && !@api_user.try(:active) - epp_errors << { - msg: 'Authentication error; server closing connection (API user is not active)', - code: '2501' - } - - success = false - end - - if success && @api_user.cannot?(:create, :epp_login) - epp_errors << { - msg: 'Authentication error; server closing connection (API user does not have epp role)', - code: '2501' - } - - success = false - end - - if success && !ip_white? - epp_errors << { - msg: 'Authentication error; server closing connection (IP is not whitelisted)', - code: '2501' - } - - success = false - end - - if success && EppSession.limit_reached?(@api_user.registrar) - epp_errors << { - msg: 'Authentication error; server closing connection (connection limit reached)', - code: '2501' - } - - success = false - end - - if success - if params[:parsed_frame].css('newPW').first - unless @api_user.update(plain_text_password: params[:parsed_frame].css('newPW').first.text) - response.headers['X-EPP-Returncode'] = '2500' - handle_errors(@api_user) and return + success = false end end - epp_session = EppSession.new - epp_session.session_id = epp_session_id - epp_session.user = @api_user - epp_session.save! - render_epp_response('login_success') - else - response.headers['X-EPP-Returncode'] = '2500' - handle_errors + if !Rails.env.development? && (!webclient_request && @api_user) + unless @api_user.pki_ok?(request.env['HTTP_SSL_CLIENT_CERT'], + request.env['HTTP_SSL_CLIENT_S_DN_CN']) + epp_errors << { + msg: 'Authentication error; server closing connection (certificate is not valid)', + code: '2501' + } + + success = false + end + end + + if success && !@api_user + epp_errors << { + msg: 'Authentication error; server closing connection (API user not found)', + code: '2501' + } + + success = false + end + + if success && !@api_user.try(:active) + epp_errors << { + msg: 'Authentication error; server closing connection (API user is not active)', + code: '2501' + } + + success = false + end + + if success && @api_user.cannot?(:create, :epp_login) + epp_errors << { + msg: 'Authentication error; server closing connection (API user does not have epp role)', + code: '2501' + } + + success = false + end + + if success && !ip_white? + epp_errors << { + msg: 'Authentication error; server closing connection (IP is not whitelisted)', + code: '2501' + } + + success = false + end + + if success && EppSession.limit_reached?(@api_user.registrar) + epp_errors << { + msg: 'Authentication error; server closing connection (connection limit reached)', + code: '2501' + } + + success = false + end + + if success + if params[:parsed_frame].css('newPW').first + unless @api_user.update(plain_text_password: params[:parsed_frame].css('newPW').first.text) + handle_errors(@api_user) and return + end + end + + epp_session = EppSession.new + epp_session.session_id = epp_session_id + epp_session.user = @api_user + epp_session.save! + render_epp_response('login_success') + else + handle_errors end end - def ip_white? - webclient_request = ENV['webclient_ips'].split(',').map(&:strip).include?(request.ip) - return true if webclient_request - if @api_user - return false unless @api_user.registrar.api_ip_white?(request.ip) - end - true - end - - def logout - unless signed_in? - epp_errors << { - code: 2201, - msg: 'Authorization error' - } - handle_errors - return + def ip_white? + webclient_request = ENV['webclient_ips'].split(',').map(&:strip).include?(request.ip) + return true if webclient_request + if @api_user + return false unless @api_user.registrar.api_ip_white?(request.ip) + end + true end - @api_user = current_user # cache current_user for logging - epp_session.destroy - response.headers['X-EPP-Returncode'] = '1500' - render_epp_response('logout') + def logout + unless signed_in? + epp_errors << { + code: 2201, + msg: 'Authorization error' + } + handle_errors + return + end + + @api_user = current_user # cache current_user for logging + epp_session.destroy + render_epp_response('logout') end - ### HELPER METHODS ### + ### HELPER METHODS ### - def login_params - user = params[:parsed_frame].css('clID').first.text - pw = params[:parsed_frame].css('pw').first.text - { username: user, plain_text_password: pw } - end + def login_params + user = params[:parsed_frame].css('clID').first.text + pw = params[:parsed_frame].css('pw').first.text + { username: user, plain_text_password: pw } + end - private - def resource - @api_user + private + + def resource + @api_user + end end end diff --git a/app/controllers/epp_controller.rb b/app/controllers/epp_controller.rb deleted file mode 100644 index 496526d71..000000000 --- a/app/controllers/epp_controller.rb +++ /dev/null @@ -1,417 +0,0 @@ -class EppController < ApplicationController - layout false - protect_from_forgery with: :null_session - skip_before_action :verify_authenticity_token - - before_action :ensure_session_id_passed - before_action :generate_svtrid - before_action :latin_only - before_action :validate_against_schema - before_action :validate_request - before_action :update_epp_session, if: 'signed_in?' - - around_action :catch_epp_errors - - helper_method :current_user - helper_method :resource - - def validate_against_schema - return if ['hello', 'error', 'keyrelay'].include?(params[:action]) - schema.validate(params[:nokogiri_frame]).each do |error| - epp_errors << { - code: 2001, - msg: error - } - response.headers['X-EPP-Returncode'] = '2200' - end - handle_errors and return if epp_errors.any? - end - - - def catch_epp_errors - err = catch(:epp_error) do - yield - nil - end - return unless err - @errors = [err] - handle_errors - end - - - rescue_from StandardError do |e| - @errors ||= [] - - if e.class == CanCan::AccessDenied - if @errors.blank? - @errors = [{ - msg: t('errors.messages.epp_authorization_error'), - code: '2201' - }] - end - else - if @errors.blank? - @errors = [{ - msg: 'Internal error.', - code: '2400' - }] - end - - if Rails.env.test? || Rails.env.development? - puts e.backtrace.reverse.join("\n") - puts "\n BACKTRACE REVERSED!\n" - puts "\n FROM-EPP-RESCUE: #{e.message}\n\n\n" - else - logger.error "FROM-EPP-RESCUE: #{e.message}" - logger.error e.backtrace.join("\n") - end - end - - render_epp_response '/epp/error' - end - - def schema - EPP_ALL_SCHEMA - end - - def generate_svtrid - @svTRID = "ccReg-#{format('%010d', rand(10**10))}" - end - - def params_hash # TODO: THIS IS DEPRECATED AND WILL BE REMOVED IN FUTURE - @params_hash ||= Hash.from_xml(params[:frame]).with_indifferent_access - end - - def epp_session - EppSession.find_by(session_id: epp_session_id) - end - - def current_user - return unless signed_in? - epp_session.user - end - - # ERROR + RESPONSE HANDLING - def epp_errors - @errors ||= [] - end - - def handle_errors(obj = nil) - @errors ||= [] - - if obj - obj.construct_epp_errors - @errors += obj.errors[:epp_errors] - end - - if params[:parsed_frame].at_css('update') - @errors.each_with_index do |errors, index| - if errors[:code] == '2304' && - errors[:value].present? && - errors[:value][:val] == DomainStatus::SERVER_DELETE_PROHIBITED && - errors[:value][:obj] == 'status' - @errors[index][:value][:val] = DomainStatus::PENDING_UPDATE - end - end - end - - # for debugging - if @errors.blank? - @errors << { - code: '1', - msg: 'handle_errors was executed when there were actually no errors' - } - end - - @errors.uniq! - - logger.error "\nFOLLOWING ERRORS OCCURRED ON EPP QUERY:" - logger.error @errors.inspect - logger.error "\n" - - # Requested by client, ticket #2688 - # Known issues: error request is exactly 1 second slower and server can handle less load - sleep 1 if !Rails.env.test? || !Rails.env.development? - - render_epp_response '/epp/error' - end - - def render_epp_response(*args) - @response = render_to_string(*args) - render xml: @response - write_to_epp_log - end - - # VALIDATION - def latin_only - return true if params['frame'].blank? - if params['frame'].match?(/\A[\p{Latin}\p{Z}\p{P}\p{S}\p{Cc}\p{Cf}\w_\'\+\-\.\(\)\/]*\Z/i) - return true - end - - epp_errors << { - msg: 'Parameter value policy error. Allowed only Latin characters.', - code: '2306' - } - - handle_errors and return false - end - - # VALIDATION - def validate_request - validation_method = "validate_#{params[:action]}" - return unless respond_to?(validation_method, true) - send(validation_method) - - # validate legal document's type here because it may be in most of the requests - @prefix = nil - if element_count('extdata > legalDocument').positive? - requires_attribute('extdata > legalDocument', 'type', values: LegalDocument::TYPES, policy: true) - end - - handle_errors and return if epp_errors.any? - end - - # let's follow grape's validations: https://github.com/intridea/grape/#parameter-validation-and-coercion - - # Adds error to epp_errors if element is missing or blank - # Returns last element of selectors if it exists - # - # requires 'transfer' - # - # TODO: Add possibility to pass validations / options in the method - - def requires(*selectors) - options = selectors.extract_options! - allow_blank = options[:allow_blank] ||= false # allow_blank is false by default - - el, missing = nil, nil - selectors.each do |selector| - full_selector = [@prefix, selector].compact.join(' ') - attr = selector.split('>').last.strip.underscore - el = params[:parsed_frame].css(full_selector).first - - if allow_blank - missing = el.nil? - else - missing = el.present? ? el.text.blank? : true - end - epp_errors << { - code: '2003', - msg: I18n.t('errors.messages.required_parameter_missing', key: "#{full_selector} [#{attr}]") - } if missing - end - - missing ? false : el # return last selector if it was present - end - - # Adds error to epp_errors if element or attribute is missing or attribute attribute is not one - # of the values - # - # requires_attribute 'transfer', 'op', values: %(approve, query, reject) - - def requires_attribute(element_selector, attribute_selector, options) - element = requires(element_selector, allow_blank: options[:allow_blank]) - return unless element - - attribute = element[attribute_selector] - - unless attribute - epp_errors << { - code: '2003', - msg: I18n.t('errors.messages.required_parameter_missing', key: attribute_selector) - } - return - end - - return if options[:values].include?(attribute) - - if options[:policy] - epp_errors << { - code: '2306', - msg: I18n.t('attribute_is_invalid', attribute: attribute_selector) - } - else - epp_errors << { - code: '2004', - msg: I18n.t('parameter_value_range_error', key: attribute_selector) - } - end - end - - def optional_attribute(element_selector, attribute_selector, options) - full_selector = [@prefix, element_selector].compact.join(' ') - element = params[:parsed_frame].css(full_selector).first - return unless element - - attribute = element[attribute_selector] - return if (attribute && options[:values].include?(attribute)) || !attribute - - epp_errors << { - code: '2306', - msg: I18n.t('attribute_is_invalid', attribute: attribute_selector) - } - end - - def exactly_one_of(*selectors) - full_selectors = create_full_selectors(*selectors) - return if element_count(*full_selectors, use_prefix: false) == 1 - - epp_errors << { - code: '2306', - msg: I18n.t(:exactly_one_parameter_required, params: full_selectors.join(' OR ')) - } - end - - def mutually_exclusive(*selectors) - full_selectors = create_full_selectors(*selectors) - return if element_count(*full_selectors, use_prefix: false) <= 1 - - epp_errors << { - code: '2306', - msg: I18n.t(:mutally_exclusive_params, params: full_selectors.join(', ')) - } - end - - def optional(selector, *validations) - full_selector = [@prefix, selector].compact.join(' ') - el = params[:parsed_frame].css(full_selector).first - return unless el&.text.present? - value = el.text - - validations.each do |x| - validator = "#{x.first[0]}_validator".camelize.constantize - err = validator.validate_epp(selector.split(' ').last, value) - epp_errors << err if err - end - end - - # Returns how many elements were present in the request - # if use_prefix is true, @prefix will be prepended to selectors e.g create > create > name - # default is true - # - # @prefix = 'create > create >' - # element_count 'name', 'registrar', use_prefix: false - # => 2 - - def element_count(*selectors) - options = selectors.extract_options! - use_prefix = options[:use_prefix] != false # use_prefix is true by default - - present_count = 0 - selectors.each do |selector| - full_selector = use_prefix ? [@prefix, selector].compact.join(' ') : selector - el = params[:parsed_frame].css(full_selector).first - present_count += 1 if el && el.text.present? - end - present_count - end - - def create_full_selectors(*selectors) - selectors.map { |x| [@prefix, x].compact.join(' ') } - end - - def xml_attrs_present?(ph, attributes) # TODO: THIS IS DEPRECATED AND WILL BE REMOVED IN FUTURE - attributes.each do |x| - epp_errors << { - code: '2003', - msg: I18n.t('errors.messages.required_parameter_missing', key: x.last) - } unless has_attribute(ph, x) - end - epp_errors.empty? - end - - def has_attribute(ph, path) # TODO: THIS IS DEPRECATED AND WILL BE REMOVED IN FUTURE - path.reduce(ph) do |location, key| - location.respond_to?(:keys) ? location[key] : nil - end - end - - def write_to_epp_log - request_command = params[:command] || params[:action] # error receives :command, other methods receive :action - frame = params[:raw_frame] || params[:frame] - - # filter pw - if request_command == 'login' && frame.present? - frame.gsub!(/pw>.+<\//, 'pw>[FILTERED]]+)>([^<])+<\/eis:legalDocument>/, "[FILTERED]") if frame.present? - - ApiLog::EppLog.create({ - request: trimmed_request, - request_command: request_command, - request_successful: epp_errors.empty?, - request_object: resource ? "#{params[:epp_object_type]}: #{resource.class} - #{resource.id} - #{resource.name}" : params[:epp_object_type], - response: @response, - api_user_name: @api_user.try(:username) || current_user.try(:username) || 'api-public', - api_user_registrar: @api_user.try(:registrar).try(:to_s) || current_user.try(:registrar).try(:to_s), - ip: request.ip, - uuid: request.uuid - }) - end - - def resource - name = self.class.to_s.sub("Epp::","").sub("Controller","").underscore.singularize - instance_variable_get("@#{name}") - end - - private - - def signed_in? - epp_session - end - - def epp_session_id - cookies[:session] # Passed by mod_epp https://github.com/mod-epp/mod-epp#requestscript-interface - end - - def ensure_session_id_passed - raise 'EPP session id is empty' unless epp_session_id.present? - end - - def update_epp_session - iptables_counter_update - - if session_timeout_reached? - @api_user = current_user # cache current_user for logging - epp_session.destroy - response.headers['X-EPP-Returncode'] = '1500' - - epp_errors << { - msg: t('session_timeout'), - code: '2201' - } - - handle_errors and return - else - epp_session.update_column(:updated_at, Time.zone.now) - end - end - - def session_timeout_reached? - timeout = 5.minutes - epp_session.updated_at < (Time.zone.now - timeout) - end - - def iptables_counter_update - return if ENV['iptables_counter_enabled'].blank? && ENV['iptables_counter_enabled'] != 'true' - return if current_user.blank? - counter_update(current_user.registrar_code, ENV['iptables_server_ip']) - end - - def counter_update(registrar_code, ip) - counter_proc = "/proc/net/xt_recent/#{registrar_code}" - - begin - File.open(counter_proc, 'a') do |f| - f.puts "+#{ip}" - end - rescue Errno::ENOENT => e - logger.error "IPTABLES COUNTER UPDATE: cannot open #{counter_proc}: #{e}" - rescue Errno::EACCES => e - logger.error "IPTABLES COUNTER UPDATE: no permission #{counter_proc}: #{e}" - rescue IOError => e - logger.error "IPTABLES COUNTER UPDATE: cannot write #{ip} to #{counter_proc}: #{e}" - end - end -end diff --git a/app/controllers/registrant/contacts_controller.rb b/app/controllers/registrant/contacts_controller.rb index a4b335def..49070ebde 100644 --- a/app/controllers/registrant/contacts_controller.rb +++ b/app/controllers/registrant/contacts_controller.rb @@ -1,10 +1,12 @@ class Registrant::ContactsController < RegistrantController helper_method :domain helper_method :fax_enabled? + helper_method :domain_filter_params skip_authorization_check only: %i[edit update] + before_action :set_contact, only: [:show] def show - @contact = current_user_contacts.find(params[:id]) + @requester_contact = Contact.find_by(ident: current_registrant_user.ident) authorize! :read, @contact end @@ -29,6 +31,13 @@ class Registrant::ContactsController < RegistrantController private + def set_contact + id = params[:id] + contact = domain.contacts.find_by(id: id) || current_user_contacts.find_by(id: id) + contact ||= Contact.find_by(id: id, ident: domain.registrant.ident) + @contact = contact + end + def domain current_user_domains.find(params[:domain_id]) end @@ -99,4 +108,8 @@ class Registrant::ContactsController < RegistrantController http.request(request) end end + + def domain_filter_params + params.permit(:domain_filter) + end end diff --git a/app/controllers/registrant/domain_delete_confirms_controller.rb b/app/controllers/registrant/domain_delete_confirms_controller.rb index 59492fefb..337ca2403 100644 --- a/app/controllers/registrant/domain_delete_confirms_controller.rb +++ b/app/controllers/registrant/domain_delete_confirms_controller.rb @@ -4,6 +4,7 @@ class Registrant::DomainDeleteConfirmsController < RegistrantController def show return if params[:confirmed] || params[:rejected] + @domain = Domain.find(params[:id]) @domain = nil unless @domain.registrant_delete_confirmable?(params[:token]) end @@ -16,28 +17,28 @@ class Registrant::DomainDeleteConfirmsController < RegistrantController end @registrant_verification = RegistrantVerification.new(domain_id: @domain.id, - domain_name: @domain.name, verification_token: params[:token]) initiator = current_registrant_user ? current_registrant_user.username : t(:user_not_authenticated) - if params[:rejected] - if @registrant_verification.domain_registrant_delete_reject!("email link #{initiator}") - flash[:notice] = t(:registrant_domain_verification_rejected) - redirect_to registrant_domain_delete_confirm_path(@domain.id, rejected: true) - else - flash[:alert] = t(:registrant_domain_delete_rejected_failed) - return render 'show' - end - elsif params[:confirmed] - if @registrant_verification.domain_registrant_delete_confirm!("email link #{initiator}") - flash[:notice] = t(:registrant_domain_verification_confirmed) - redirect_to registrant_domain_delete_confirm_path(@domain.id, confirmed: true) - else - flash[:alert] = t(:registrant_domain_delete_confirmed_failed) - return render 'show' - end + confirmed = params[:confirmed] ? true : false + action = if confirmed + @registrant_verification.domain_registrant_delete_confirm!("email link #{initiator}") + else + @registrant_verification.domain_registrant_delete_reject!("email link #{initiator}") + end + + fail_msg = t("registrant_domain_delete_#{confirmed ? 'confirmed' : 'rejected'}_failed".to_sym) + success_msg = t("registrant_domain_verification_#{confirmed ? 'confirmed' : 'rejected'}".to_sym) + + flash[:alert] = action ? success_msg : fail_msg + (render 'show' && return) unless action + + if confirmed + redirect_to registrant_domain_delete_confirm_path(@domain.id, confirmed: true) + else + redirect_to registrant_domain_delete_confirm_path(@domain.id, rejected: true) end end end diff --git a/app/controllers/registrant/domain_update_confirms_controller.rb b/app/controllers/registrant/domain_update_confirms_controller.rb index d0bc1e7a1..0e4f2a582 100644 --- a/app/controllers/registrant/domain_update_confirms_controller.rb +++ b/app/controllers/registrant/domain_update_confirms_controller.rb @@ -16,7 +16,6 @@ class Registrant::DomainUpdateConfirmsController < RegistrantController end @registrant_verification = RegistrantVerification.new(domain_id: @domain.id, - domain_name: @domain.name, verification_token: params[:token]) initiator = current_registrant_user ? current_registrant_user.username : @@ -32,6 +31,8 @@ class Registrant::DomainUpdateConfirmsController < RegistrantController end elsif params[:confirmed] if @registrant_verification.domain_registrant_change_confirm!("email link, #{initiator}") + Dispute.close_by_domain(@domain.name) if @domain.disputed? + flash[:notice] = t(:registrant_domain_verification_confirmed) redirect_to registrant_domain_update_confirm_path(@domain.id, confirmed: true) else diff --git a/app/controllers/registrant/domains_controller.rb b/app/controllers/registrant/domains_controller.rb index b8cd8f37a..216f87e54 100644 --- a/app/controllers/registrant/domains_controller.rb +++ b/app/controllers/registrant/domains_controller.rb @@ -4,11 +4,29 @@ class Registrant::DomainsController < RegistrantController params[:q] ||= {} normalize_search_parameters do - @q = current_user_domains.search(params[:q]) - @domains = @q.result.page(params[:page]) + @q = current_user_domains.search(search_params) end - @domains = @domains.per(params[:results_per_page]) if params[:results_per_page].to_i.positive? + domains = @q.result + + respond_to do |format| + format.html do + @domains = domains.page(params[:page]) + domains_per_page = params[:results_per_page].to_i + @domains = @domains.per(domains_per_page) if domains_per_page.positive? + end + format.csv do + raw_csv = @q.result.to_csv + send_data raw_csv, filename: 'domains.csv', type: "#{Mime[:csv]}; charset=utf-8" + end + format.pdf do + view = ActionView::Base.new(ActionController::Base.view_paths, domains: domains) + raw_html = view.render(file: 'registrant/domains/list_pdf', layout: false) + raw_pdf = domains.pdf(raw_html) + + send_data raw_pdf, filename: 'domains.pdf' + end + end end def show @@ -32,23 +50,6 @@ class Registrant::DomainsController < RegistrantController end end - def download_list - authorize! :view, :registrant_domains - params[:q] ||= {} - normalize_search_parameters do - @q = current_user_domains.search(params[:q]) - @domains = @q - end - - respond_to do |format| - format.csv { render text: @domains.result.to_csv } - format.pdf do - pdf = @domains.result.pdf(render_to_string('registrant/domains/download_list', layout: false)) - send_data pdf, filename: 'domains.pdf' - end - end - end - private def normalize_search_parameters @@ -70,4 +71,9 @@ class Registrant::DomainsController < RegistrantController registrant_domain_delete_confirm_url(token: domain.registrant_verification_token) end end -end \ No newline at end of file + + def search_params + params.require(:q).permit(:name_matches, :registrant_ident_eq, :valid_to_gteq, :valid_to_lteq, + :results_per_page) + end +end diff --git a/app/controllers/registrant_controller.rb b/app/controllers/registrant_controller.rb index 6589d6f89..1e97281e7 100644 --- a/app/controllers/registrant_controller.rb +++ b/app/controllers/registrant_controller.rb @@ -1,5 +1,6 @@ class RegistrantController < ApplicationController before_action :authenticate_registrant_user! + before_action :set_paper_trail_whodunnit layout 'registrant/application' include Registrant::ApplicationHelper @@ -33,4 +34,4 @@ class RegistrantController < ApplicationController flash.now[:notice] = t('registrant.company_register_unavailable') current_registrant_user.direct_domains end -end \ No newline at end of file +end diff --git a/app/controllers/registrar/base_controller.rb b/app/controllers/registrar/base_controller.rb index 499d44594..54bed977b 100644 --- a/app/controllers/registrar/base_controller.rb +++ b/app/controllers/registrar/base_controller.rb @@ -6,6 +6,7 @@ class Registrar before_action :check_ip_restriction helper_method :depp_controller? helper_method :head_title_sufix + before_action :set_paper_trail_whodunnit protected diff --git a/app/controllers/registrar/contacts_controller.rb b/app/controllers/registrar/contacts_controller.rb index f343f9bfb..18af3a29f 100644 --- a/app/controllers/registrar/contacts_controller.rb +++ b/app/controllers/registrar/contacts_controller.rb @@ -3,6 +3,7 @@ class Registrar before_action :init_epp_contact helper_method :address_processing? helper_method :ident_types + helper_method :domain_filter_params def index authorize! :view, Depp::Contact @@ -16,51 +17,40 @@ class Registrar search_params[:registrant_domains_id_not_null] = 1 end - if search_params.length == 1 && search_params[:name_matches].present? - @contacts = Contact.find_by(name: search_params[:name_matches]) - end + contacts = current_registrar_user.registrar.contacts.includes(:registrar) + status_list = params[:statuses_contains] - if params[:statuses_contains] - contacts = current_registrar_user.registrar.contacts.includes(:registrar).where( - "contacts.statuses @> ?::varchar[]", "{#{params[:statuses_contains].join(',')}}" - ) - else - contacts = current_registrar_user.registrar.contacts.includes(:registrar) + 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.search(search_params) - @contacts = @q.result(distinct: :true).page(params[:page]) end - @contacts = @contacts.per(params[:results_per_page]) if params[:results_per_page].to_i.positive? - end - - def download_list - authorize! :view, Depp::Contact - - params[:q] ||= {} - params[:q].delete_if { |_k, v| v.blank? } - if params[:q].length == 1 && params[:q][:name_matches].present? - @contacts = Contact.find_by(name: params[:q][:name_matches]) - end - - contacts = current_registrar_user.registrar.contacts.includes(:registrar) - contacts = contacts.filter_by_states(params[:statuses_contains]) if params[:statuses_contains] - - normalize_search_parameters do - @q = contacts.search(params[:q]) - @contacts = @q.result - end + contacts = @q.result respond_to do |format| - format.csv { render text: @contacts.to_csv } + 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 = contacts.to_csv + send_data raw_csv, filename: 'contacts.csv', type: "#{Mime[:csv]}; charset=utf-8" + end format.pdf do - pdf = @contacts.pdf(render_to_string('registrar/contacts/download_list', layout: false)) - send_data pdf, filename: 'contacts.pdf' + view = ActionView::Base.new(ActionController::Base.view_paths, contacts: contacts) + view.class_eval { include ::ApplicationHelper } + raw_html = view.render(file: 'registrar/contacts/list_pdf', layout: false) + raw_pdf = contacts.pdf(raw_html) + + send_data raw_pdf, filename: 'contacts.pdf' end end - end def new @@ -80,7 +70,7 @@ class Registrar def create authorize! :create, Depp::Contact - @contact = Depp::Contact.new(params[:depp_contact]) + @contact = Depp::Contact.new(contact_params) if @contact.save redirect_to registrar_contact_url(@contact.id) @@ -91,9 +81,9 @@ class Registrar def update authorize! :edit, Depp::Contact - @contact = Depp::Contact.new(params[:depp_contact]) + @contact = Depp::Contact.new(contact_params) - if @contact.update_attributes(params[:depp_contact]) + if @contact.update_attributes(contact_params) redirect_to registrar_contact_url(@contact.id) else render 'edit' @@ -107,7 +97,7 @@ class Registrar def destroy authorize! :delete, Depp::Contact - @contact = Depp::Contact.new(params[:depp_contact]) + @contact = Depp::Contact.new(contact_params_for_delete) if @contact.delete redirect_to registrar_contacts_url, notice: t(:destroyed) @@ -116,6 +106,12 @@ class Registrar end end + protected + + def domain_filter_params + params.permit(:domain_filter) + end + private def init_epp_contact @@ -143,5 +139,22 @@ class Registrar 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 diff --git a/app/controllers/registrar/current_user_controller.rb b/app/controllers/registrar/current_user_controller.rb index 624ee294e..3a214322c 100644 --- a/app/controllers/registrar/current_user_controller.rb +++ b/app/controllers/registrar/current_user_controller.rb @@ -6,7 +6,7 @@ class Registrar raise 'Cannot switch to unlinked user' unless current_registrar_user.linked_with?(new_user) sign_in(:registrar_user, new_user) - redirect_to :back, notice: t('.switched', new_user: new_user) + redirect_back(fallback_location: root_path, notice: t('.switched', new_user: new_user)) end private diff --git a/app/controllers/registrar/domains_controller.rb b/app/controllers/registrar/domains_controller.rb index d2969bb69..50ad0bd10 100644 --- a/app/controllers/registrar/domains_controller.rb +++ b/app/controllers/registrar/domains_controller.rb @@ -2,16 +2,17 @@ class Registrar class DomainsController < DeppController before_action :init_domain, except: :new helper_method :contacts + helper_method :search_params def index authorize! :view, Depp::Domain - params[:q] ||= {} - params[:q].delete_if { |_k, v| v.blank? } - if params[:q].length == 1 && params[:q][:name_matches].present? - @domain = Domain.find_by(name: params[:q][:name_matches]) - if @domain - redirect_to info_registrar_domains_url(domain_name: @domain.name) and return + 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]) + + if domain + redirect_to info_registrar_domains_url(domain_name: domain.name) and return end end @@ -24,15 +25,15 @@ class Registrar end normalize_search_parameters do - @q = domains.search(params[:q]) + @q = domains.search(search_params) @domains = @q.result.page(params[:page]) - if @domains.count == 0 && params[:q][:name_matches] !~ /^%.+%$/ - # if we do not get any results, add wildcards to the name field and search again - n_cache = params[:q][:name_matches] - params[:q][:name_matches] = "%#{params[:q][:name_matches]}%" - @q = domains.search(params[:q]) + + # 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 + new_search_params[:name_matches] = "%#{new_search_params[:name_matches]}%" + @q = domains.search(new_search_params) @domains = @q.result.page(params[:page]) - params[:q][:name_matches] = n_cache # we don't want to show wildcards in search form end end @@ -47,9 +48,10 @@ class Registrar domain_presenters << ::DomainPresenter.new(domain: domain, view: view_context) end - csv = Registrar::DomainListCSVPresenter.new(domains: domain_presenters, view: view_context).to_s + raw_csv = Registrar::DomainListCSVPresenter.new(domains: domain_presenters, + view: view_context).to_s filename = "Domains_#{l(Time.zone.now, format: :filename)}.csv" - send_data(csv, filename: filename) + send_data raw_csv, filename: filename, type: "#{Mime[:csv]}; charset=utf-8" end end end @@ -57,6 +59,7 @@ class Registrar def info authorize! :info, Depp::Domain @data = @domain.info(params[:domain_name]) if params[:domain_name] + @client_holded = client_holded(@data) if response_ok? render 'info' else @@ -83,7 +86,7 @@ class Registrar def create authorize! :create, Depp::Domain - @domain_params = params[:domain] + @domain_params = domain_params.to_h @data = @domain.create(@domain_params) if response_ok? @@ -97,12 +100,14 @@ class Registrar 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 response_ok? redirect_to info_registrar_domains_url(domain_name: @domain_params[:name]) @@ -151,29 +156,60 @@ class Registrar 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 contacts current_registrar_user.registrar.contacts end def normalize_search_parameters - ca_cache = params[:q][:valid_to_lteq] + ca_cache = search_params[: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) + 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 - params[:q][:valid_to_lteq] = ca_cache + 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 diff --git a/app/controllers/registrar/keyrelays_controller.rb b/app/controllers/registrar/keyrelays_controller.rb deleted file mode 100644 index 8436bb679..000000000 --- a/app/controllers/registrar/keyrelays_controller.rb +++ /dev/null @@ -1,20 +0,0 @@ -class Registrar - class KeyrelaysController < DeppController - def show - authorize! :view, Depp::Keyrelay - end - - def create - authorize! :create, Depp::Keyrelay - keyrelay = Depp::Keyrelay.new(current_user: depp_current_user) - @data = keyrelay.keyrelay(params) - - if response_ok? - flash[:epp_results] = [{ 'code' => '1000', 'msg' => 'Command completed successfully', 'show' => true }] - redirect_to registrar_keyrelay_path - else - render 'show' - end - end - end -end diff --git a/app/controllers/registrar/payments_controller.rb b/app/controllers/registrar/payments_controller.rb index 5be0d6562..598d13446 100644 --- a/app/controllers/registrar/payments_controller.rb +++ b/app/controllers/registrar/payments_controller.rb @@ -5,48 +5,51 @@ class Registrar 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 + + before_action :check_supported_payment_method, only: [:pay] def pay invoice = Invoice.find(params[:invoice_id]) - bank = params[:bank] - opts = { - return_url: registrar_return_payment_with_url( - bank, invoice_id: invoice - ), - response_url: registrar_response_payment_with_url( - bank, invoice_id: invoice - ) - } - @payment = ::PaymentOrders.create_with_type(bank, invoice, opts) - @payment.create_transaction + 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 - invoice = Invoice.find(params[:invoice_id]) - opts = { response: params } - @payment = ::PaymentOrders.create_with_type(params[:bank], invoice, opts) - if @payment.valid_response_from_intermediary? && @payment.settled_payment? - @payment.complete_transaction + @payment_order = PaymentOrder.find_by!(id: params[:payment_order]) + @payment_order.update!(response: params.to_unsafe_h) - if invoice.paid? - flash[:notice] = t(:pending_applied) + if @payment_order.payment_received? + @payment_order.complete_transaction + + if @payment_order.invoice.paid? + flash[:notice] = t('.payment_successful') else - flash[:alert] = t(:something_wrong) + flash[:alert] = t('.successful_payment_backend_error') end else - flash[:alert] = t(:something_wrong) + @payment_order.create_failure_report + flash[:alert] = t('.payment_not_received') end - redirect_to registrar_invoice_path(invoice) + redirect_to registrar_invoice_path(@payment_order.invoice) end def callback - invoice = Invoice.find(params[:invoice_id]) - opts = { response: params } - @payment = ::PaymentOrders.create_with_type(params[:bank], invoice, opts) + @payment_order = PaymentOrder.find_by!(id: params[:payment_order]) + @payment_order.update!(response: params.to_unsafe_h) - if @payment.valid_response_from_intermediary? && @payment.settled_payment? - @payment.complete_transaction + if @payment_order.payment_received? + @payment_order.complete_transaction + else + @payment_order.create_failure_report end render status: 200, json: { status: 'ok' } @@ -55,13 +58,9 @@ class Registrar private def check_supported_payment_method - return if supported_payment_method? - raise StandardError.new("Not supported payment method") - end + return if PaymentOrder.supported_method?(params[:bank], shortname: true) - - def supported_payment_method? - PaymentOrders::PAYMENT_METHODS.include?(params[:bank]) + raise(StandardError, 'Not supported payment method') end end end diff --git a/app/controllers/registrar/polls_controller.rb b/app/controllers/registrar/polls_controller.rb index ab0d5e1a6..3e17bf2b7 100644 --- a/app/controllers/registrar/polls_controller.rb +++ b/app/controllers/registrar/polls_controller.rb @@ -26,21 +26,6 @@ class Registrar render 'show' end - # TODO: Keyrelay is disabled for now - # def confirm_keyrelay - # authorize! :confirm, :keyrelay - # domain_params = params[:domain] - # @data = @domain.confirm_keyrelay(domain_params) - - # if response_ok? - # redirect_to info_registrar_domains_url(domain_name: domain_params[:name]) - # else - # @results = @data.css('result') - # @data = depp_current_user.request(@ex.poll) - # render 'show' - # end - # end - def confirm_transfer domain_params = params[:domain] @data = @domain.confirm_transfer(domain_params) diff --git a/app/controllers/registrar/sessions_controller.rb b/app/controllers/registrar/sessions_controller.rb index c97c3155d..5bebe5619 100644 --- a/app/controllers/registrar/sessions_controller.rb +++ b/app/controllers/registrar/sessions_controller.rb @@ -31,7 +31,8 @@ class Registrar end if @depp_user.pki - unless @api_user.registrar_pki_ok?(request.env['HTTP_SSL_CLIENT_CERT'], request.env['HTTP_SSL_CLIENT_S_DN_CN']) + unless @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 end @@ -55,7 +56,7 @@ class Registrar ip_allowed = restricted_ip.can_access_registrar_area?(resource.registrar) unless ip_allowed - render text: t('registrar.authorization.ip_not_allowed', ip: request.ip) + render plain: t('registrar.authorization.ip_not_allowed', ip: request.ip) warden.logout(:registrar_user) return end @@ -171,7 +172,7 @@ class Registrar return if allowed - render text: t('registrar.authorization.ip_not_allowed', ip: request.ip) + render plain: t('registrar.authorization.ip_not_allowed', ip: request.ip) end def current_ability @@ -205,4 +206,4 @@ class Registrar redirect_to new_registrar_user_session_url, alert: @depp_user.errors.full_messages.first end end -end \ No newline at end of file +end diff --git a/app/controllers/registrar/xml_consoles_controller.rb b/app/controllers/registrar/xml_consoles_controller.rb index 083dec532..b07b9cbee 100644 --- a/app/controllers/registrar/xml_consoles_controller.rb +++ b/app/controllers/registrar/xml_consoles_controller.rb @@ -19,7 +19,7 @@ class Registrar xml_dir_path = Rails.root + 'app/views/registrar/xml_consoles/epp_requests' xml = File.read("#{xml_dir_path}/#{params[:obj]}/#{params[:epp_action]}.xml") xml.gsub!('ABC-12345', "#{cl_trid}") - render text: xml + render plain: xml end end end diff --git a/app/controllers/repp/v1/auctions_controller.rb b/app/controllers/repp/v1/auctions_controller.rb new file mode 100644 index 000000000..4a5265d13 --- /dev/null +++ b/app/controllers/repp/v1/auctions_controller.rb @@ -0,0 +1,23 @@ +module Repp + module V1 + class AuctionsController < ActionController::API + def index + auctions = Auction.started + + render json: { count: auctions.count, + auctions: auctions_to_json(auctions) } + end + + private + + def auctions_to_json(auctions) + auctions.map do |e| + { + domain_name: e.domain, + punycode_domain_name: SimpleIDN.to_ascii(e.domain), + } + end + end + end + end +end diff --git a/app/controllers/repp/v1/retained_domains_controller.rb b/app/controllers/repp/v1/retained_domains_controller.rb new file mode 100644 index 000000000..c1bb458e9 --- /dev/null +++ b/app/controllers/repp/v1/retained_domains_controller.rb @@ -0,0 +1,15 @@ +module Repp + module V1 + class RetainedDomainsController < ActionController::API + def index + domains = RetainedDomains.new(query_params) + + render json: { count: domains.count, domains: domains.to_jsonable } + end + + def query_params + params.permit(:type) + end + end + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index a4a8e4912..5c742afce 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -33,6 +33,18 @@ module ApplicationHelper end end + def current_commit_link + hash = `git rev-parse --short HEAD` + current_repo = `git remote get-url origin`.gsub('com:', 'com/') + .gsub('git@', 'https://') + .gsub('.git', '') + + link_to hash.to_s, "#{current_repo}/commit/#{hash}", + class: 'footer-version-link', + target: '_blank', + rel: 'noopener' + end + def creator_link(model) return 'not present' if model.blank? return 'unknown' if model.creator.blank? @@ -96,4 +108,14 @@ module ApplicationHelper def body_css_class [controller_path.split('/').map!(&:dasherize), action_name.dasherize, 'page'].join('-') end -end \ No newline at end of file + + def verified_email_span(verification) + content_tag(:span, verification.email, class: verified_email_class(verification)) + end + + def verified_email_class(verification) + return 'text-danger' if verification.failed? + return 'text-primary' if verification.not_verified? + return 'text-success' if verification.verified? + end +end diff --git a/app/jobs/directo_invoice_forward_job.rb b/app/jobs/directo_invoice_forward_job.rb new file mode 100644 index 000000000..6c3eb034c --- /dev/null +++ b/app/jobs/directo_invoice_forward_job.rb @@ -0,0 +1,125 @@ +class DirectoInvoiceForwardJob < Que::Job + def run(monthly: false, dry: false) + @dry = dry + (@month = Time.zone.now - 1.month) if monthly + api_url = ENV['directo_invoice_url'] + sales_agent = Setting.directo_sales_agent + payment_term = Setting.directo_receipt_payment_term + @prepayment_product_id = Setting.directo_receipt_product_name + + @client = DirectoApi::Client.new(api_url, sales_agent, payment_term) + monthly ? send_monthly_invoices : send_receipts + end + + def send_receipts + unsent_invoices = Invoice.where(in_directo: false).non_cancelled + + Rails.logger.info("[DIRECTO] Trying to send #{unsent_invoices.count} prepayment invoices") + unsent_invoices.each do |invoice| + unless valid_invoice_conditions?(invoice) + Rails.logger.info "[DIRECTO] Invoice #{invoice.number} has been skipped" + next + end + @client.invoices.add_with_schema(invoice: invoice.as_directo_json, schema: 'prepayment') + end + + sync_with_directo + end + + def send_monthly_invoices + Registrar.where.not(test_registrar: true).find_each do |registrar| + fetch_monthly_summary(registrar: registrar) + end + + return unless @client.invoices.count.positive? + + sync_with_directo + end + + def fetch_monthly_summary(registrar:) + return unless registrar.cash_account + + summary = registrar.monthly_summary(month: @month) + @client.invoices.add_with_schema(invoice: summary, schema: 'summary') unless summary.nil? + end + + def assign_monthly_numbers + if directo_counter_exceedable?(@client.invoices.count) + raise 'Directo Counter is going to be out of period!' + end + + min_directo = Setting.directo_monthly_number_min.presence.try(:to_i) + directo_number = [Setting.directo_monthly_number_last.presence.try(:to_i), + min_directo].compact.max || 0 + + @client.invoices.each do |inv| + directo_number += 1 + inv.number = directo_number + end + end + + def valid_invoice_conditions?(invoice) + if invoice.account_activity.nil? || invoice.account_activity.bank_transaction.nil? || + invoice.account_activity.bank_transaction.sum.nil? || + invoice.account_activity.bank_transaction.sum != invoice.total + return false + + end + + true + end + + def sync_with_directo + assign_monthly_numbers if @month + Rails.logger.info("[Directo] - attempting to send following XML:\n #{@client.invoices.as_xml}") + return if @dry + + res = @client.invoices.deliver(ssl_verify: false) + process_directo_response(res.body, @client.invoices.as_xml) + rescue SocketError, Errno::ECONNREFUSED, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, + EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError + Rails.logger.info('[Directo] Failed to communicate via API') + end + + def process_directo_response(xml, req) + Rails.logger.info "[Directo] - Responded with body: #{xml}" + Nokogiri::XML(xml).css('Result').each do |res| + if @month + mark_invoice_as_sent(res: res, req: req) + else + inv = Invoice.find_by(number: res.attributes['docid'].value.to_i) + mark_invoice_as_sent(invoice: inv, res: res, req: req) + end + end + end + + def mark_invoice_as_sent(invoice: nil, res:, req:) + directo_record = Directo.new(response: res.as_json.to_h, + request: req, invoice_number: res.attributes['docid'].value.to_i) + if invoice + directo_record.item = invoice + invoice.update(in_directo: true) + else + update_directo_number(num: directo_record.invoice_number) + end + + directo_record.save! + end + + def update_directo_number(num:) + return unless num.to_i > Setting.directo_monthly_number_last.to_i + + Setting.directo_monthly_number_last = num.to_i + end + + def directo_counter_exceedable?(invoice_count) + min_directo = Setting.directo_monthly_number_min.presence.try(:to_i) + max_directo = Setting.directo_monthly_number_max.presence.try(:to_i) + last_directo = [Setting.directo_monthly_number_last.presence.try(:to_i), + min_directo].compact.max || 0 + + return true if max_directo && max_directo < (last_directo + invoice_count) + + false + end +end diff --git a/app/jobs/dispute_status_update_job.rb b/app/jobs/dispute_status_update_job.rb new file mode 100644 index 000000000..547d56868 --- /dev/null +++ b/app/jobs/dispute_status_update_job.rb @@ -0,0 +1,63 @@ +class DisputeStatusUpdateJob < Que::Job + def run(logger: Logger.new(STDOUT)) + @logger = logger + + @backlog = { 'activated': 0, 'closed': 0, 'activate_fail': [], 'close_fail': [] } + .with_indifferent_access + + close_disputes + activate_disputes + + @logger.info "DisputeStatusUpdateJob - All done. Closed #{@backlog['closed']} and " \ + "activated #{@backlog['activated']} disputes." + + show_failed_disputes unless @backlog['activate_fail'].empty? && @backlog['close_fail'].empty? + end + + def close_disputes + disputes = Dispute.where(closed: nil).where('expires_at < ?', Time.zone.today).all + @logger.info "DisputeStatusUpdateJob - Found #{disputes.count} closable disputes" + disputes.each do |dispute| + process_dispute(dispute, closing: true) + end + end + + def activate_disputes + disputes = Dispute.where(closed: nil, starts_at: Time.zone.today).all + @logger.info "DisputeStatusUpdateJob - Found #{disputes.count} activatable disputes" + + disputes.each do |dispute| + process_dispute(dispute, closing: false) + end + end + + def process_dispute(dispute, closing: false) + intent = closing ? 'close' : 'activate' + success = closing ? dispute.close(initiator: 'Job') : dispute.generate_data + create_backlog_entry(dispute: dispute, intent: intent, successful: success) + end + + def create_backlog_entry(dispute:, intent:, successful:) + if successful + @backlog["#{intent}d"] += 1 + @logger.info "DisputeStatusUpdateJob - #{intent}d dispute " \ + " for '#{dispute.domain_name}'" + else + @backlog["#{intent}_fail"] << dispute.id + @logger.info 'DisputeStatusUpdateJob - Failed to' \ + "#{intent} dispute for '#{dispute.domain_name}'" + end + end + + def show_failed_disputes + if @backlog['close_fail'].any? + @logger.info('DisputeStatusUpdateJob - Failed to close disputes with Ids:' \ + "#{@backlog['close_fail']}") + end + + return unless @backlog['activate_fail'].any? + + @logger.info('DisputeStatusUpdateJob - Failed to activate disputes with Ids:' \ + "#{@backlog['activate_fail']}") + end +end diff --git a/app/jobs/domain_delete_confirm_job.rb b/app/jobs/domain_delete_confirm_job.rb index a067ce175..e94f2432c 100644 --- a/app/jobs/domain_delete_confirm_job.rb +++ b/app/jobs/domain_delete_confirm_job.rb @@ -1,6 +1,6 @@ class DomainDeleteConfirmJob < Que::Job def run(domain_id, action, initiator = nil) - ::PaperTrail.whodunnit = "job - #{self.class.name} - #{action} by #{initiator}" + ::PaperTrail.request.whodunnit = "job - #{self.class.name} - #{action} by #{initiator}" # it's recommended to keep transaction against job table as short as possible. ActiveRecord::Base.transaction do domain = Epp::Domain.find(domain_id) diff --git a/app/jobs/domain_delete_job.rb b/app/jobs/domain_delete_job.rb index b45f96713..43e0bb844 100644 --- a/app/jobs/domain_delete_job.rb +++ b/app/jobs/domain_delete_job.rb @@ -3,7 +3,7 @@ class DomainDeleteJob < Que::Job def run(domain_id) domain = Domain.find(domain_id) - ::PaperTrail.whodunnit = "job - #{self.class.name}" + ::PaperTrail.request.whodunnit = "job - #{self.class.name}" WhoisRecord.where(domain_id: domain.id).destroy_all domain.destroy diff --git a/app/jobs/domain_update_confirm_job.rb b/app/jobs/domain_update_confirm_job.rb index 376858c42..f3665f1e8 100644 --- a/app/jobs/domain_update_confirm_job.rb +++ b/app/jobs/domain_update_confirm_job.rb @@ -1,6 +1,6 @@ class DomainUpdateConfirmJob < Que::Job def run(domain_id, action, initiator = nil) - ::PaperTrail.whodunnit = "job - #{self.class.name} - #{action} by #{initiator}" + ::PaperTrail.request.whodunnit = "job - #{self.class.name} - #{action} by #{initiator}" # it's recommended to keep transaction against job table as short as possible. ActiveRecord::Base.transaction do domain = Epp::Domain.find(domain_id) diff --git a/app/jobs/regenerate_subzone_whoises_job.rb b/app/jobs/regenerate_subzone_whoises_job.rb new file mode 100644 index 000000000..280fa4088 --- /dev/null +++ b/app/jobs/regenerate_subzone_whoises_job.rb @@ -0,0 +1,11 @@ +class RegenerateSubzoneWhoisesJob < Que::Job + def run + subzones = DNS::Zone.all + + subzones.each do |zone| + next unless zone.subzone? + + UpdateWhoisRecordJob.enqueue zone.origin, 'zone' + end + end +end diff --git a/app/jobs/send_e_invoice_job.rb b/app/jobs/send_e_invoice_job.rb new file mode 100644 index 000000000..e281db14d --- /dev/null +++ b/app/jobs/send_e_invoice_job.rb @@ -0,0 +1,43 @@ +class SendEInvoiceJob < Que::Job + def run(invoice_id) + invoice = run_condition(Invoice.find_by(id: invoice_id)) + + invoice.to_e_invoice.deliver + ActiveRecord::Base.transaction do + invoice.update(e_invoice_sent_at: Time.zone.now) + log_success(invoice) + destroy + end + rescue StandardError => e + log_error(invoice: invoice, error: e) + raise e + end + + private + + def run_condition(invoice) + destroy unless invoice + destroy if invoice.do_not_send_e_invoice? + invoice + end + + def log_success(invoice) + id = invoice.try(:id) || invoice + message = "E-Invoice for an invoice with ID # #{id} was sent successfully" + logger.info message + end + + def log_error(invoice:, error:) + id = invoice.try(:id) || invoice + message = <<~TEXT.squish + There was an error sending e-invoice for invoice with ID # #{id}. + The error message was the following: #{error} + This job will retry. + TEXT + logger.error message + end + + def logger + Rails.logger + end +end diff --git a/app/jobs/update_whois_record_job.rb b/app/jobs/update_whois_record_job.rb index bee0e032c..2973d5a6b 100644 --- a/app/jobs/update_whois_record_job.rb +++ b/app/jobs/update_whois_record_job.rb @@ -1,16 +1,12 @@ class UpdateWhoisRecordJob < Que::Job def run(names, type) - ::PaperTrail.whodunnit = "job - #{self.class.name} - #{type}" + ::PaperTrail.request.whodunnit = "job - #{self.class.name} - #{type}" - klass = case type - when 'reserved'then ReservedDomain - when 'blocked' then BlockedDomain - when 'domain' then Domain - end + klass = determine_class(type) Array(names).each do |name| - record = klass.find_by(name: name) + record = find_record(klass, name) if record send "update_#{type}", record else @@ -19,7 +15,19 @@ class UpdateWhoisRecordJob < Que::Job end end + def find_record(klass, name) + klass == DNS::Zone ? klass.find_by(origin: name) : klass.find_by(name: name) + end + def determine_class(type) + case type + when 'reserved' then ReservedDomain + when 'blocked' then BlockedDomain + when 'domain' then Domain + when 'disputed' then Dispute.active + when 'zone' then DNS::Zone + end + end def update_domain(domain) domain.whois_record ? domain.whois_record.save : domain.create_whois_record @@ -33,6 +41,13 @@ class UpdateWhoisRecordJob < Que::Job update_reserved(record) end + def update_disputed(record) + update_reserved(record) + end + + def update_zone(record) + update_reserved(record) + end # 1. deleting own # 2. trying to regenerate reserved in order domain is still in the list @@ -41,14 +56,32 @@ class UpdateWhoisRecordJob < Que::Job BlockedDomain.find_by(name: name).try(:generate_data) ReservedDomain.find_by(name: name).try(:generate_data) + Dispute.active.find_by(domain_name: name).try(:generate_data) end def delete_reserved(name) - Domain.where(name: name).any? - Whois::Record.where(name: name).delete_all + remove_status_from_whois(domain_name: name, domain_status: 'Reserved') end def delete_blocked(name) delete_reserved(name) end + + def delete_disputed(name) + return if Dispute.active.find_by(domain_name: name).present? + + remove_status_from_whois(domain_name: name, domain_status: 'disputed') + end + + def delete_zone(name) + WhoisRecord.where(name: name).destroy_all + Whois::Record.where(name: name).destroy_all + end + + def remove_status_from_whois(domain_name:, domain_status:) + Whois::Record.where(name: domain_name).each do |r| + r.json['status'] = r.json['status'].delete_if { |status| status == domain_status } + r.json['status'].blank? ? r.destroy : r.save + end + end end diff --git a/app/jobs/verify_emails_job.rb b/app/jobs/verify_emails_job.rb new file mode 100644 index 000000000..75f4b7d91 --- /dev/null +++ b/app/jobs/verify_emails_job.rb @@ -0,0 +1,45 @@ +class VerifyEmailsJob < Que::Job + def run(verification_id) + email_address_verification = run_condition(EmailAddressVerification.find(verification_id)) + + return if email_address_verification.recently_verified? + + ActiveRecord::Base.transaction do + email_address_verification.verify + log_success(email_address_verification) + destroy + end + rescue StandardError => e + log_error(verification: email_address_verification, error: e) + raise e + end + + private + + def run_condition(email_address_verification) + destroy unless email_address_verification + destroy if email_address_verification.recently_verified? + + email_address_verification + end + + def logger + @logger ||= Logger.new(Rails.root.join('log', 'email_verification.log')) + end + + def log_success(verification) + email = verification.try(:email) || verification + message = "Email address #{email} verification done" + logger.info message + end + + def log_error(verification:, error:) + email = verification.try(:email) || verification + message = <<~TEXT.squish + There was an error verifying email #{email}. + The error message was the following: #{error} + This job will retry. + TEXT + logger.error message + end +end diff --git a/app/mailers/domain_delete_mailer.rb b/app/mailers/domain_delete_mailer.rb index eaac1a5af..1f08204bf 100644 --- a/app/mailers/domain_delete_mailer.rb +++ b/app/mailers/domain_delete_mailer.rb @@ -39,10 +39,12 @@ class DomainDeleteMailer < ApplicationMailer @registrant = RegistrantPresenter.new(registrant: registrant, view: view_context) @redemption_grace_period = Setting.redemption_grace_period + @expire_warning_period = Setting.expire_warning_period + @delete_period_length = @redemption_grace_period + @expire_warning_period subject = default_i18n_subject(domain_name: domain.name) mail(from: forced_email_from, - to: domain.primary_contact_emails, + to: domain.force_delete_contact_emails, subject: subject, template_path: 'mailers/domain_delete_mailer/forced', template_name: template_name) diff --git a/app/models/ability.rb b/app/models/ability.rb index 50e87c98e..0e18f433a 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -34,8 +34,6 @@ class Ability if @user.registrar.api_ip_white?(@ip) can :manage, :poll can :manage, Depp::Contact - # can :manage, Depp::Keyrelay # TODO: Keyrelay is disabled for now - # can :confirm, :keyrelay # TODO: Keyrelay is disabled for now can :manage, :xml_console can :manage, Depp::Domain end @@ -48,13 +46,13 @@ class Ability # can(:create, :epp_request) # Epp::Domain - can(:info, Epp::Domain) { |d, pw| d.registrar_id == @user.registrar_id || pw.blank? ? true : d.transfer_code == pw } + can(:info, Epp::Domain) can(:check, Epp::Domain) can(:create, Epp::Domain) can(:renew, Epp::Domain) { |d| d.registrar_id == @user.registrar_id } + can(:remove_hold, Epp::Domain) { |d| d.registrar_id == @user.registrar_id } can(:update, Epp::Domain) { |d, pw| d.registrar_id == @user.registrar_id || d.transfer_code == pw } - can(:transfer, Epp::Domain) { |d, pw| d.transfer_code == pw } - can(:view_password, Epp::Domain) { |d, pw| d.registrar_id == @user.registrar_id || d.transfer_code == pw } + can(:transfer, Epp::Domain) can(:delete, Epp::Domain) { |d, pw| d.registrar_id == @user.registrar_id || d.transfer_code == pw } # Epp::Contact @@ -65,6 +63,7 @@ class Ability can(:update, Epp::Contact) { |c, pw| c.registrar_id == @user.registrar_id || c.auth_info == pw } can(:delete, Epp::Contact) { |c, pw| c.registrar_id == @user.registrar_id || c.auth_info == pw } can(:renew, Epp::Contact) + can(:transfer, Epp::Contact) can(:view_password, Epp::Contact) { |c, pw| c.registrar_id == @user.registrar_id || c.auth_info == pw } end @@ -95,13 +94,13 @@ class Ability can :manage, ApiUser can :manage, AdminUser can :manage, Certificate - can :manage, Keyrelay can :manage, LegalDocument can :manage, BankStatement can :manage, BankTransaction can :manage, Invoice can :manage, WhiteIp can :manage, AccountActivity + can :manage, Dispute can :read, ApiLog::EppLog can :read, ApiLog::ReppLog can :update, :pending diff --git a/app/models/account.rb b/app/models/account.rb index b7c43eab3..420f43e48 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -1,4 +1,4 @@ -class Account < ActiveRecord::Base +class Account < ApplicationRecord include Versions belongs_to :registrar, required: true diff --git a/app/models/account_activity.rb b/app/models/account_activity.rb index c5857631e..d8e6be4d4 100644 --- a/app/models/account_activity.rb +++ b/app/models/account_activity.rb @@ -1,4 +1,4 @@ -class AccountActivity < ActiveRecord::Base +class AccountActivity < ApplicationRecord include Versions belongs_to :account, required: true belongs_to :bank_transaction diff --git a/app/models/action.rb b/app/models/action.rb index 1d4f30d86..273dee821 100644 --- a/app/models/action.rb +++ b/app/models/action.rb @@ -1,5 +1,5 @@ -class Action < ActiveRecord::Base - has_paper_trail class_name: 'ActionVersion' +class Action < ApplicationRecord + has_paper_trail versions: { class_name: 'ActionVersion' } belongs_to :user belongs_to :contact @@ -16,4 +16,4 @@ class Action < ActiveRecord::Base raise 'Action object is missing' unless contact "contact_#{operation}".to_sym end -end \ No newline at end of file +end diff --git a/app/models/actions/contact_update.rb b/app/models/actions/contact_update.rb new file mode 100644 index 000000000..f8b39ecb4 --- /dev/null +++ b/app/models/actions/contact_update.rb @@ -0,0 +1,105 @@ +module Actions + class ContactUpdate + attr_reader :contact + attr_reader :new_attributes + attr_reader :legal_document + attr_reader :ident + attr_reader :user + + def initialize(contact, new_attributes, legal_document, ident, user) + @contact = contact + @new_attributes = new_attributes + @legal_document = legal_document + @ident = ident + @user = user + end + + def call + maybe_remove_address + maybe_update_statuses + maybe_update_ident + maybe_attach_legal_doc + commit + end + + def maybe_remove_address + return if Contact.address_processing? + + new_attributes.delete(:city) + new_attributes.delete(:zip) + new_attributes.delete(:street) + new_attributes.delete(:state) + new_attributes.delete(:country_code) + end + + def maybe_update_statuses + return unless Setting.client_status_editing_enabled + + new_statuses = + contact.statuses - new_attributes[:statuses_to_remove] + new_attributes[:statuses_to_add] + + new_attributes[:statuses] = new_statuses + end + + def maybe_attach_legal_doc + return unless legal_document + + document = contact.legal_documents.create( + document_type: legal_document[:type], + body: legal_document[:body] + ) + + contact.legal_document_id = document.id + end + + def maybe_update_ident + return unless ident[:ident] + + if contact.identifier.valid? + submitted_ident = ::Contact::Ident.new(code: ident[:ident], + type: ident[:ident_type], + country_code: ident[:ident_country_code]) + + if submitted_ident != contact.identifier + contact.add_epp_error('2308', nil, nil, I18n.t('epp.contacts.errors.valid_ident')) + @error = true + end + else + ident_update_attempt = ident[:ident] != contact.ident + + if ident_update_attempt + contact.add_epp_error('2308', nil, nil, I18n.t('epp.contacts.errors.ident_update')) + @error = true + end + + identifier = ::Contact::Ident.new(code: ident[:ident], + type: ident[:ident_type], + country_code: ident[:ident_country_code]) + + identifier.validate + + contact.identifier = identifier + contact.ident_updated_at ||= Time.zone.now + end + end + + def commit + return false if @error + + contact.upid = user.registrar&.id + contact.up_date = Time.zone.now + + contact.attributes = new_attributes + + email_changed = contact.will_save_change_to_email? + old_email = contact.email_was + updated = contact.save + + if updated && email_changed && contact.registrant? + ContactMailer.email_changed(contact: contact, old_email: old_email).deliver_now + end + + updated + end + end +end diff --git a/app/models/admin_user.rb b/app/models/admin_user.rb index 07686e921..159578ab0 100644 --- a/app/models/admin_user.rb +++ b/app/models/admin_user.rb @@ -4,7 +4,7 @@ class AdminUser < User validates :identity_code, presence: true, if: -> { country_code == 'EE' } validates :email, presence: true validates :password, :password_confirmation, presence: true, if: :new_record? - validates :password_confirmation, presence: true, if: :encrypted_password_changed? + validates :password_confirmation, presence: true, if: :will_save_change_to_encrypted_password? validate :validate_identity_code, if: -> { country_code == 'EE' } ROLES = %w(user customer_service admin) # should not match to api_users roles diff --git a/app/models/api_log/db.rb b/app/models/api_log/db.rb index 255caffda..ca1162e8f 100644 --- a/app/models/api_log/db.rb +++ b/app/models/api_log/db.rb @@ -1,5 +1,5 @@ module ApiLog - class Db < ActiveRecord::Base + class Db < ApplicationRecord self.abstract_class = true # to_sym is needed because passing a string to ActiveRecord::Base.establish_connection # for a configuration lookup is deprecated diff --git a/app/models/api_user.rb b/app/models/api_user.rb index d08f17380..d7b264495 100644 --- a/app/models/api_user.rb +++ b/app/models/api_user.rb @@ -26,9 +26,9 @@ class ApiUser < User validates :username, uniqueness: true delegate :code, :name, to: :registrar, prefix: true + delegate :legaldoc_mandatory?, to: :registrar alias_attribute :login, :username - attr_accessor :registrar_typeahead SUPER = 'super' EPP = 'epp' @@ -44,7 +44,7 @@ class ApiUser < User after_initialize :set_defaults def set_defaults return unless new_record? - self.active = true unless active_changed? + self.active = true unless saved_change_to_active? end class << self @@ -53,10 +53,6 @@ class ApiUser < User end end - def registrar_typeahead - @registrar_typeahead || registrar || nil - end - def to_s username end @@ -69,24 +65,14 @@ class ApiUser < User registrar.notifications.unread end - def registrar_pki_ok?(crt, cn) - return false if crt.blank? || cn.blank? - crt = crt.split(' ').join("\n") - crt.gsub!("-----BEGIN\nCERTIFICATE-----\n", "-----BEGIN CERTIFICATE-----\n") - crt.gsub!("\n-----END\nCERTIFICATE-----", "\n-----END CERTIFICATE-----") - cert = OpenSSL::X509::Certificate.new(crt) - md5 = OpenSSL::Digest::MD5.new(cert.to_der).to_s - certificates.registrar.exists?(md5: md5, common_name: cn) - end + def pki_ok?(crt, com, api: true) + return false if crt.blank? || com.blank? - def api_pki_ok?(crt, cn) - return false if crt.blank? || cn.blank? - crt = crt.split(' ').join("\n") - crt.gsub!("-----BEGIN\nCERTIFICATE-----\n", "-----BEGIN CERTIFICATE-----\n") - crt.gsub!("\n-----END\nCERTIFICATE-----", "\n-----END CERTIFICATE-----") - cert = OpenSSL::X509::Certificate.new(crt) + origin = api ? certificates.api : certificates.registrar + cert = machine_readable_certificate(crt) md5 = OpenSSL::Digest::MD5.new(cert.to_der).to_s - certificates.api.exists?(md5: md5, common_name: cn) + + origin.exists?(md5: md5, common_name: com, revoked: false) end def linked_users @@ -98,4 +84,14 @@ class ApiUser < User def linked_with?(another_api_user) another_api_user.identity_code == self.identity_code end + + private + + def machine_readable_certificate(cert) + cert = cert.split(' ').join("\n") + cert.gsub!("-----BEGIN\nCERTIFICATE-----\n", "-----BEGIN CERTIFICATE-----\n") + cert.gsub!("\n-----END\nCERTIFICATE-----", "\n-----END CERTIFICATE-----") + + OpenSSL::X509::Certificate.new(cert) + end end diff --git a/app/models/application_record.rb b/app/models/application_record.rb new file mode 100644 index 000000000..10a4cba84 --- /dev/null +++ b/app/models/application_record.rb @@ -0,0 +1,3 @@ +class ApplicationRecord < ActiveRecord::Base + self.abstract_class = true +end diff --git a/app/models/auction.rb b/app/models/auction.rb index 80df11eef..791184d60 100644 --- a/app/models/auction.rb +++ b/app/models/auction.rb @@ -1,4 +1,4 @@ -class Auction < ActiveRecord::Base +class Auction < ApplicationRecord enum status: { started: 'started', awaiting_payment: 'awaiting_payment', @@ -23,10 +23,19 @@ class Auction < ActiveRecord::Base save! end + def whois_deadline + registration_deadline.try(:to_s, :iso8601) + end + def mark_as_no_bids no_bids! end + def mark_deadline(registration_deadline) + self.registration_deadline = registration_deadline + save! + end + def mark_as_payment_received self.status = self.class.statuses[:payment_received] generate_registration_code @@ -69,4 +78,4 @@ class Auction < ActiveRecord::Base def registration_code_matches?(code) registration_code == code end -end \ No newline at end of file +end diff --git a/app/models/bank_statement.rb b/app/models/bank_statement.rb index 5997927cf..c73e6bb44 100644 --- a/app/models/bank_statement.rb +++ b/app/models/bank_statement.rb @@ -1,4 +1,4 @@ -class BankStatement < ActiveRecord::Base +class BankStatement < ApplicationRecord include Versions has_many :bank_transactions @@ -25,10 +25,16 @@ class BankStatement < ActiveRecord::Base bank_transactions.build(bt_params) end + prepare_dir self.import_file_path = "#{ENV['bank_statement_import_dir']}/#{Time.zone.now.to_formatted_s(:number)}.txt" File.open(import_file_path, 'w') { |f| f.write(th6_file.open.read) } end + def prepare_dir + dirname = ENV['bank_statement_import_dir'] + FileUtils.mkdir_p(dirname) unless File.directory?(dirname) + end + def parse_th6_row(row) return parse_th6_header(row) if row[4, 3].strip == '000' return if row[4, 3].strip == '999' # skip footer @@ -45,7 +51,7 @@ class BankStatement < ActiveRecord::Base buyer_name: row[83, 35].strip, document_no: row[118, 8].strip, description: row[126, 140].strip, - sum: BigDecimal.new(row[268, 12].strip) / BigDecimal.new('100.0'), + sum: BigDecimal(row[268, 12].strip) / BigDecimal('100.0'), reference_no: row[280, 35].strip } end @@ -80,7 +86,9 @@ class BankStatement < ActiveRecord::Base status == FULLY_BINDED end - def bind_invoices - bank_transactions.unbinded.each(&:autobind_invoice) + def bind_invoices(manual: false) + bank_transactions.unbinded.each do |transaction| + transaction.autobind_invoice(manual: manual) + end end end diff --git a/app/models/bank_transaction.rb b/app/models/bank_transaction.rb index eb8c84622..f53a286ba 100644 --- a/app/models/bank_transaction.rb +++ b/app/models/bank_transaction.rb @@ -1,4 +1,4 @@ -class BankTransaction < ActiveRecord::Base +class BankTransaction < ApplicationRecord include Versions belongs_to :bank_statement has_one :account_activity @@ -13,53 +13,72 @@ class BankTransaction < ActiveRecord::Base def binded_invoice return unless binded? + account_activity.invoice end - - def invoice_num - return @invoice_no if defined?(@invoice_no) - - match = description.match(/^[^\d]*(\d+)/) - return unless match - - @invoice_no = match[1].try(:to_i) - end - def invoice - @invoice ||= registrar.invoices.find_by(number: invoice_num) if registrar + return unless registrar + + @invoice ||= registrar.invoices + .order(created_at: :asc) + .unpaid + .non_cancelled + .find_by(total: sum) end def registrar - @registrar ||= Invoice.find_by(reference_no: reference_no)&.buyer + @registrar ||= Invoice.find_by(reference_no: parsed_ref_number)&.buyer end - # For successful binding, reference number, invoice id and sum must match with the invoice - def autobind_invoice + def autobind_invoice(manual: false) return if binded? return unless registrar - return unless invoice_num return unless invoice return unless invoice.payable? - return if invoice.total != sum - create_activity(registrar, invoice) + channel = if manual + 'admin_payment' + else + 'system_payment' + end + create_internal_payment_record(channel: channel, invoice: invoice, + registrar: registrar) end - def bind_invoice(invoice_no) + def create_internal_payment_record(channel: nil, invoice:, registrar:) + if channel.nil? + create_activity(invoice.buyer, invoice) + return + end + + payment_order = PaymentOrder.new_with_type(type: channel, invoice: invoice) + payment_order.save! + + if create_activity(registrar, invoice) + payment_order.paid! + else + payment_order.update(notes: 'Failed to create activity', status: 'failed') + end + end + + def bind_invoice(invoice_no, manual: false) if binded? errors.add(:base, I18n.t('transaction_is_already_binded')) return end invoice = Invoice.find_by(number: invoice_no) + errors.add(:base, I18n.t('invoice_was_not_found')) unless invoice + validate_invoice_data(invoice) + return if errors.any? - unless invoice - errors.add(:base, I18n.t('invoice_was_not_found')) - return - end + create_internal_payment_record(channel: (manual ? 'admin_payment' : nil), invoice: invoice, + registrar: invoice.buyer) + end + def validate_invoice_data(invoice) if invoice.paid? errors.add(:base, I18n.t('invoice_is_already_binded')) return @@ -70,23 +89,21 @@ class BankTransaction < ActiveRecord::Base return end - if invoice.total != sum - errors.add(:base, I18n.t('invoice_and_transaction_sums_do_not_match')) - return - end - - create_activity(invoice.buyer, invoice) + errors.add(:base, I18n.t('invoice_and_transaction_sums_do_not_match')) if invoice.total != sum end def create_activity(registrar, invoice) - ActiveRecord::Base.transaction do - create_account_activity!(account: registrar.cash_account, - invoice: invoice, - sum: invoice.subtotal, - currency: currency, - description: description, - activity_type: AccountActivity::ADD_CREDIT) + activity = AccountActivity.new( + account: registrar.cash_account, bank_transaction: self, + invoice: invoice, sum: invoice.subtotal, + currency: currency, description: description, + activity_type: AccountActivity::ADD_CREDIT + ) + if activity.save reset_pending_registrar_balance_reload + true + else + false end end @@ -98,4 +115,12 @@ class BankTransaction < ActiveRecord::Base registrar.settings['balance_auto_reload'].delete('pending') registrar.save! end + + def parsed_ref_number + reference_no || ref_number_from_description + end + + def ref_number_from_description + /(\d{7})/.match(description)[0] + end end diff --git a/app/models/billing/price.rb b/app/models/billing/price.rb index b48c9f0bb..283a6e5bc 100644 --- a/app/models/billing/price.rb +++ b/app/models/billing/price.rb @@ -1,5 +1,5 @@ module Billing - class Price < ActiveRecord::Base + class Price < ApplicationRecord include Concerns::Billing::Price::Expirable belongs_to :zone, class_name: 'DNS::Zone', required: true diff --git a/app/models/blocked_domain.rb b/app/models/blocked_domain.rb index 26d5fedd7..d292827dc 100644 --- a/app/models/blocked_domain.rb +++ b/app/models/blocked_domain.rb @@ -1,4 +1,4 @@ -class BlockedDomain < ActiveRecord::Base +class BlockedDomain < ApplicationRecord include Versions before_save :generate_data after_destroy :remove_data diff --git a/app/models/certificate.rb b/app/models/certificate.rb index 212114862..d2428365a 100644 --- a/app/models/certificate.rb +++ b/app/models/certificate.rb @@ -1,6 +1,6 @@ require 'open3' -class Certificate < ActiveRecord::Base +class Certificate < ApplicationRecord include Versions belongs_to :api_user @@ -32,20 +32,21 @@ class Certificate < ActiveRecord::Base errors.add(:base, I18n.t(:invalid_csr_or_crt)) end - before_create :parse_metadata - def parse_metadata - if crt - pc = parsed_crt.try(:subject).try(:to_s) || '' - cn = pc.scan(/\/CN=(.+)/).flatten.first - self.common_name = cn.split('/').first - self.md5 = OpenSSL::Digest::MD5.new(parsed_crt.to_der).to_s - self.interface = API - elsif csr - pc = parsed_csr.try(:subject).try(:to_s) || '' - cn = pc.scan(/\/CN=(.+)/).flatten.first - self.common_name = cn.split('/').first - self.interface = REGISTRAR - end + validate :assign_metadata, on: :create + + def assign_metadata + origin = crt ? parsed_crt : parsed_csr + parse_metadata(origin) + rescue NoMethodError + errors.add(:base, I18n.t(:invalid_csr_or_crt)) + end + + def parse_metadata(origin) + pc = origin.subject.to_s + cn = pc.scan(%r{\/CN=(.+)}).flatten.first + self.common_name = cn.split('/').first + self.md5 = OpenSSL::Digest::MD5.new(origin.to_der).to_s if crt + self.interface = crt ? API : REGISTRAR end def parsed_crt @@ -116,6 +117,7 @@ class Certificate < ActiveRecord::Base -revoke #{crt_file.path} -key '#{ENV['ca_key_password']}' -batch") if err.match(/Data Base Updated/) || err.match(/ERROR:Already revoked/) + self.revoked = true save! @cached_status = REVOKED else diff --git a/app/models/certification_request.rb b/app/models/certification_request.rb new file mode 100644 index 000000000..1ea81c120 --- /dev/null +++ b/app/models/certification_request.rb @@ -0,0 +1,3 @@ +class CertificationRequest + extend ActiveModel::Translation +end \ No newline at end of file diff --git a/app/models/concerns/contact/transferable.rb b/app/models/concerns/contact/transferable.rb index 3f151251a..987933a8d 100644 --- a/app/models/concerns/contact/transferable.rb +++ b/app/models/concerns/contact/transferable.rb @@ -3,7 +3,7 @@ module Concerns::Contact::Transferable included do validates :auth_info, presence: true - after_initialize :generate_auth_info, if: 'new_record? && auth_info.blank?' + after_initialize :generate_auth_info, if: -> { new_record? && auth_info.blank? } end def transfer(new_registrar) diff --git a/app/models/concerns/domain/disputable.rb b/app/models/concerns/domain/disputable.rb new file mode 100644 index 000000000..a05d7cea6 --- /dev/null +++ b/app/models/concerns/domain/disputable.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module Concerns + module Domain + module Disputable + extend ActiveSupport::Concern + + included do + validate :validate_disputed + end + + def mark_as_disputed + statuses.push(DomainStatus::DISPUTED) unless statuses.include?(DomainStatus::DISPUTED) + save + end + + def unmark_as_disputed + statuses.delete_if { |status| status == DomainStatus::DISPUTED } + save + end + + def in_disputed_list? + @in_disputed_list ||= Dispute.active.find_by(domain_name: name).present? + end + + def disputed? + Dispute.active.where(domain_name: name).any? + end + + def validate_disputed + return if persisted? || !in_disputed_list? + + if reserved_pw.blank? + errors.add(:base, :required_parameter_missing_disputed) + return false + end + + return if Dispute.valid_auth?(name, reserved_pw) + + errors.add(:base, :invalid_auth_information_reserved) + end + end + end +end diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb index 5247ce93d..af3aaa7c7 100644 --- a/app/models/concerns/domain/force_delete.rb +++ b/app/models/concerns/domain/force_delete.rb @@ -1,32 +1,116 @@ -module Concerns::Domain::ForceDelete +module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength extend ActiveSupport::Concern + included do + store_accessor :force_delete_data, + :force_delete_type, + :contact_notification_sent_date, + :template_name + + scope :notification_not_sent, + lambda { + where("(force_delete_data->>'contact_notification_sent_date') is null") + } + end + + class_methods do + def force_delete_scheduled + where('force_delete_start <= ?', Time.zone.now) + end + end + def force_delete_scheduled? statuses.include?(DomainStatus::FORCE_DELETE) end - def schedule_force_delete + def should_notify_on_soft_force_delete? + force_delete_scheduled? && contact_notification_sent_date.blank? && + force_delete_start.to_date <= Time.zone.now.to_date && force_delete_type.to_sym == :soft && + !statuses.include?(DomainStatus::CLIENT_HOLD) + end + + def client_holdable? + force_delete_scheduled? && !statuses.include?(DomainStatus::CLIENT_HOLD) && + force_delete_start.present? && force_delete_lte_today && force_delete_lte_valid_date + end + + def force_delete_lte_today + force_delete_start + Setting.expire_warning_period.days <= Time.zone.now + end + + def force_delete_lte_valid_date + force_delete_start + Setting.expire_warning_period.days <= valid_to + end + + def schedule_force_delete(type: :fast_track) if discarded? raise StandardError, 'Force delete procedure cannot be scheduled while a domain is discarded' end + type == :fast_track ? force_delete_fast_track : force_delete_soft + end + + def add_force_delete_type(force_delete_type) + self.force_delete_type = force_delete_type + end + + def force_delete_fast_track preserve_current_statuses_for_force_delete add_force_delete_statuses - self.force_delete_date = Time.zone.today + Setting.redemption_grace_period.days + 1.day + add_force_delete_type(:fast) + self.force_delete_date = force_delete_fast_track_start_date + 1.day + self.force_delete_start = Time.zone.today + 1.day stop_all_pending_actions allow_deletion save(validate: false) end - def cancel_force_delete - restore_statuses_before_force_delete - remove_force_delete_statuses - self.force_delete_date = nil + def force_delete_soft + preserve_current_statuses_for_force_delete + add_force_delete_statuses + add_force_delete_type(:soft) + calculate_soft_delete_date + stop_all_pending_actions + allow_deletion save(validate: false) end + def clear_force_delete_data + self.force_delete_data = nil + end + + def cancel_force_delete + restore_statuses_before_force_delete + remove_force_delete_statuses + clear_force_delete_data + self.force_delete_date = nil + self.force_delete_start = nil + save(validate: false) + registrar.notifications.create!(text: I18n.t('force_delete_cancelled', domain_name: name)) + end + + def outzone_date + (force_delete_start || valid_to) + Setting.expire_warning_period.days + end + + def purge_date + (force_delete_date&.beginning_of_day || valid_to + Setting.expire_warning_period.days + + Setting.redemption_grace_period.days) + end + private + def calculate_soft_delete_date + years = (valid_to.to_date - Time.zone.today).to_i / 365 + soft_delete_dates(years) if years.positive? + end + + def soft_delete_dates(years) + self.force_delete_start = valid_to - years.years + 1.day + self.force_delete_date = force_delete_start + Setting.expire_warning_period.days + + Setting.redemption_grace_period.days + end + def stop_all_pending_actions statuses.delete(DomainStatus::PENDING_UPDATE) statuses.delete(DomainStatus::PENDING_TRANSFER) @@ -35,7 +119,7 @@ module Concerns::Domain::ForceDelete end def preserve_current_statuses_for_force_delete - self.statuses_before_force_delete = statuses + self.statuses_before_force_delete = statuses.clone end def restore_statuses_before_force_delete @@ -47,25 +131,21 @@ module Concerns::Domain::ForceDelete statuses << DomainStatus::FORCE_DELETE statuses << DomainStatus::SERVER_RENEW_PROHIBITED statuses << DomainStatus::SERVER_TRANSFER_PROHIBITED - statuses << DomainStatus::SERVER_UPDATE_PROHIBITED - statuses << DomainStatus::PENDING_DELETE - - if (statuses & [DomainStatus::SERVER_HOLD, DomainStatus::CLIENT_HOLD]).empty? - statuses << DomainStatus::SERVER_MANUAL_INZONE - end end def remove_force_delete_statuses statuses.delete(DomainStatus::FORCE_DELETE) statuses.delete(DomainStatus::SERVER_RENEW_PROHIBITED) statuses.delete(DomainStatus::SERVER_TRANSFER_PROHIBITED) - statuses.delete(DomainStatus::SERVER_UPDATE_PROHIBITED) - statuses.delete(DomainStatus::PENDING_DELETE) - statuses.delete(DomainStatus::SERVER_MANUAL_INZONE) + statuses.delete(DomainStatus::CLIENT_HOLD) end def allow_deletion statuses.delete(DomainStatus::CLIENT_DELETE_PROHIBITED) statuses.delete(DomainStatus::SERVER_DELETE_PROHIBITED) end + + def force_delete_fast_track_start_date + Time.zone.today + Setting.expire_warning_period.days + Setting.redemption_grace_period.days + end end diff --git a/app/models/concerns/domain/transferable.rb b/app/models/concerns/domain/transferable.rb index 56e77f34d..9de2fff83 100644 --- a/app/models/concerns/domain/transferable.rb +++ b/app/models/concerns/domain/transferable.rb @@ -57,7 +57,8 @@ module Concerns::Domain::Transferable def transfer_domain_contacts(new_registrar) copied_ids = [] - contacts.each do |contact| + domain_contacts.each do |dc| + contact = Contact.find(dc.contact_id) next if copied_ids.include?(contact.id) || contact.registrar == new_registrar if registrant_id_was == contact.id # registrant was copied previously, do not copy it again @@ -66,7 +67,11 @@ module Concerns::Domain::Transferable oc = contact.transfer(new_registrar) end - domain_contacts.where(contact_id: contact.id).update_all({ contact_id: oc.id }) # n+1 workaround + if domain_contacts.find_by(contact_id: oc.id, domain_id: id, type: dc.type).present? + dc.destroy + else + dc.update(contact_id: oc.id) + end copied_ids << contact.id end end diff --git a/app/models/concerns/email_verifable.rb b/app/models/concerns/email_verifable.rb new file mode 100644 index 000000000..dc512b2c8 --- /dev/null +++ b/app/models/concerns/email_verifable.rb @@ -0,0 +1,91 @@ +module Concerns + module EmailVerifable + extend ActiveSupport::Concern + + def email_verification + @email_verification ||= EmailAddressVerification.find_or_create_by(email: unicode_email, + domain: domain(email)) + end + + def billing_email_verification + return unless attribute_names.include?('billing_email') + + @billing_email_verification ||= EmailAddressVerification + .find_or_create_by(email: unicode_billing_email, + domain: domain(billing_email)) + end + + class_methods do + def domain(email) + Mail::Address.new(email).domain&.downcase || 'not_found' + rescue Mail::Field::IncompleteParseError + 'not_found' + end + + def local(email) + Mail::Address.new(email).local&.downcase || email + rescue Mail::Field::IncompleteParseError + email + end + + def punycode_to_unicode(email) + return email if domain(email) == 'not_found' + + local = local(email) + domain = SimpleIDN.to_unicode(domain(email)) + "#{local}@#{domain}"&.downcase + end + + def unicode_to_punycode(email) + return email if domain(email) == 'not_found' + + local = local(email) + domain = SimpleIDN.to_ascii(domain(email)) + "#{local}@#{domain}"&.downcase + end + end + + def unicode_billing_email + self.class.punycode_to_unicode(billing_email) + end + + def unicode_email + self.class.punycode_to_unicode(email) + end + + def domain(email) + SimpleIDN.to_unicode(self.class.domain(email)) + end + + def punycode_to_unicode(email) + self.class.punycode_to_unicode(email) + end + + def correct_email_format + return if email.blank? + + result = email_verification.verify + process_result(result: result, field: :email) + end + + def correct_billing_email_format + return if email.blank? + + result = billing_email_verification.verify + process_result(result: result, field: :billing_email) + end + + # rubocop:disable Metrics/LineLength + def process_result(result:, field:) + case result[:errors].keys.first + when :smtp + errors.add(field, I18n.t('activerecord.errors.models.contact.attributes.email.email_smtp_check_error')) + when :mx + errors.add(field, I18n.t('activerecord.errors.models.contact.attributes.email.email_mx_check_error')) + when :regex + errors.add(field, I18n.t('activerecord.errors.models.contact.attributes.email.email_regex_check_error')) + end + end + # rubocop:enable Metrics/LineLength + end +end diff --git a/app/models/concerns/epp_errors.rb b/app/models/concerns/epp_errors.rb index 7395732ca..c1e4fa2e1 100644 --- a/app/models/concerns/epp_errors.rb +++ b/app/models/concerns/epp_errors.rb @@ -20,7 +20,7 @@ module EppErrors epp_errors << collect_parent_errors(attr, errors) end - errors[:epp_errors] = epp_errors + errors.add(:epp_errors, epp_errors) errors[:epp_errors].flatten! end diff --git a/app/models/concerns/invoice/book_keeping.rb b/app/models/concerns/invoice/book_keeping.rb new file mode 100644 index 000000000..82e6506c9 --- /dev/null +++ b/app/models/concerns/invoice/book_keeping.rb @@ -0,0 +1,34 @@ +module Concerns + module Invoice + module BookKeeping + extend ActiveSupport::Concern + + def as_directo_json + invoice = ActiveSupport::JSON.decode(ActiveSupport::JSON.encode(self)) + invoice['customer'] = compose_directo_customer + invoice['issue_date'] = issue_date.strftime('%Y-%m-%d') + invoice['transaction_date'] = account_activity + .bank_transaction&.paid_at&.strftime('%Y-%m-%d') + invoice['language'] = buyer.language == 'en' ? 'ENG' : '' + invoice['invoice_lines'] = compose_directo_product + + invoice + end + + def compose_directo_product + [{ 'product_id': Setting.directo_receipt_product_name, 'description': order, + 'quantity': 1, 'price': ActionController::Base.helpers.number_with_precision( + subtotal, precision: 2, separator: '.' + ) }].as_json + end + + def compose_directo_customer + { + 'code': buyer.accounting_customer_code, + 'destination': buyer_country_code, + 'vat_reg_no': buyer_vat_no, + }.as_json + end + end + end +end diff --git a/app/models/concerns/job/force_delete.rb b/app/models/concerns/job/force_delete.rb new file mode 100644 index 000000000..316612d1e --- /dev/null +++ b/app/models/concerns/job/force_delete.rb @@ -0,0 +1,34 @@ +module Concerns + module Job + module ForceDelete + extend ActiveSupport::Concern + + class_methods do + def start_client_hold + log_prepare_client_hold + + ::PaperTrail.request.whodunnit = "cron - #{__method__}" + + ::Domain.force_delete_scheduled.each do |domain| + proceed_client_hold(domain: domain) + end + + log_end_end_force_delete_job + end + + def proceed_client_hold(domain:) + notify_on_grace_period(domain) if domain.should_notify_on_soft_force_delete? + return unless domain.client_holdable? + + domain.statuses << DomainStatus::CLIENT_HOLD + log_start_client_hold(domain) + + domain.save(validate: false) + notify_client_hold(domain) + + log_end_end_client_hold(domain) + end + end + end + end +end diff --git a/app/models/concerns/job/force_delete_logging.rb b/app/models/concerns/job/force_delete_logging.rb new file mode 100644 index 000000000..8f6ee227c --- /dev/null +++ b/app/models/concerns/job/force_delete_logging.rb @@ -0,0 +1,34 @@ +module Concerns + module Job + module ForceDeleteLogging + extend ActiveSupport::Concern + + class_methods do + def log_prepare_client_hold + return if Rails.env.test? + + STDOUT << "#{Time.zone.now.utc} - Setting client_hold to domains\n" + end + + def log_start_client_hold(domain) + return if Rails.env.test? + + STDOUT << "#{Time.zone.now.utc} DomainCron.start_client_hold: ##{domain.id} "\ + "(#{domain.name}) #{domain.changes}\n" + end + + def log_end_end_client_hold(domain) + return if Rails.env.test? + + STDOUT << "#{Time.zone.now.utc} - Successfully set client_hold on (#{domain.name})" + end + + def log_end_end_force_delete_job + return if Rails.env.test? + + STDOUT << "#{Time.zone.now.utc} - All client_hold setting are done\n" + end + end + end + end +end diff --git a/app/models/concerns/job/force_delete_notify.rb b/app/models/concerns/job/force_delete_notify.rb new file mode 100644 index 000000000..658c7a315 --- /dev/null +++ b/app/models/concerns/job/force_delete_notify.rb @@ -0,0 +1,31 @@ +module Concerns + module Job + module ForceDeleteNotify + extend ActiveSupport::Concern + + class_methods do + def notify_client_hold(domain) + domain.registrar.notifications.create!(text: I18n.t('force_delete_set_on_domain', + domain_name: domain.name, + outzone_date: domain.outzone_date, + purge_date: domain.purge_date)) + end + + def notify_on_grace_period(domain) + domain.registrar.notifications.create!(text: I18n.t('grace_period_started_domain', + domain_name: domain.name, + date: domain.force_delete_start)) + send_mail(domain) + domain.update(contact_notification_sent_date: Time.zone.today) + end + + def send_mail(domain) + DomainDeleteMailer.forced(domain: domain, + registrar: domain.registrar, + registrant: domain.registrant, + template_name: domain.template_name).deliver_now + end + end + end + end +end diff --git a/app/models/concerns/registrar/book_keeping.rb b/app/models/concerns/registrar/book_keeping.rb new file mode 100644 index 000000000..60b9c2b1a --- /dev/null +++ b/app/models/concerns/registrar/book_keeping.rb @@ -0,0 +1,128 @@ +module Concerns + module Registrar + module BookKeeping + extend ActiveSupport::Concern + + DOMAIN_TO_PRODUCT = { 'ee': '01EE', 'com.ee': '02COM', 'pri.ee': '03PRI', + 'fie.ee': '04FIE', 'med.ee': '05MED' }.freeze + + def monthly_summary(month:) + activities = monthly_activites(month) + return unless activities.any? + + invoice = { + 'number': 1, + 'customer': compose_directo_customer, + 'language': language == 'en' ? 'ENG' : '', 'currency': activities.first.currency, + 'date': month.end_of_month.strftime('%Y-%m-%d') + }.as_json + + invoice['invoice_lines'] = prepare_invoice_lines(month: month, activities: activities) + + invoice + end + + def prepare_invoice_lines(month:, activities:) + lines = [] + + lines << { 'description': title_for_summary(month) } + activities.each do |activity| + fetch_invoice_lines(activity, lines) + end + lines << prepayment_for_all(lines) + + lines.as_json + end + + def title_for_summary(date) + I18n.with_locale(language == 'en' ? 'en' : 'et') do + I18n.t('registrar.monthly_summary_title', date: I18n.l(date, format: '%B %Y')) + end + end + + def fetch_invoice_lines(activity, lines) + price = load_price(activity) + if price.duration.include? 'year' + price.duration.to_i.times do |duration| + lines << new_monthly_invoice_line(activity: activity, duration: duration + 1).as_json + end + else + lines << new_monthly_invoice_line(activity: activity).as_json + end + end + + def monthly_activites(month) + AccountActivity.where(account_id: account_ids) + .where(created_at: month.beginning_of_month..month.end_of_month) + .where(activity_type: [AccountActivity::CREATE, AccountActivity::RENEW]) + end + + def new_monthly_invoice_line(activity:, duration: nil) + price = load_price(activity) + line = { + 'product_id': DOMAIN_TO_PRODUCT[price.zone_name.to_sym], + 'quantity': 1, + 'unit': language == 'en' ? 'pc' : 'tk', + } + + finalize_invoice_line(line, price: price, duration: duration, activity: activity) + end + + def finalize_invoice_line(line, price:, activity:, duration:) + yearly = price.duration.include?('year') + + line['price'] = yearly ? (price.price.amount / price.duration.to_i) : price.price.amount + line['description'] = description_in_language(price: price, yearly: yearly) + + if duration.present? + add_product_timeframe(line: line, activity: activity, duration: duration) if duration > 1 + end + + line + end + + def add_product_timeframe(line:, activity:, duration:) + create_time = activity.created_at + line['start_date'] = (create_time + (duration - 1).year).end_of_month.strftime('%Y-%m-%d') + line['end_date'] = (create_time + (duration - 1).year + 1).end_of_month.strftime('%Y-%m-%d') + end + + def description_in_language(price:, yearly:) + timeframe_string = yearly ? 'yearly' : 'monthly' + locale_string = "registrar.invoice_#{timeframe_string}_product_description" + + I18n.with_locale(language == 'en' ? 'en' : 'et') do + I18n.t(locale_string, tld: ".#{price.zone_name}", length: price.duration.to_i) + end + end + + def prepayment_for_all(lines) + total = 0 + en = language == 'en' + lines.each { |l| total += l['quantity'].to_f * l['price'].to_f } + { + 'product_id': Setting.directo_receipt_product_name, + 'description': en ? 'Domains prepayment' : 'Domeenide ettemaks', + 'quantity': -1, + 'price': total, + 'unit': en ? 'pc' : 'tk', + } + end + + def compose_directo_customer + { + 'code': accounting_customer_code, + 'destination': address_country_code, + 'vat_reg_no': vat_no, + }.as_json + end + + def load_price(account_activity) + @pricelists ||= {} + return @pricelists[account_activity.price_id] if @pricelists.key? account_activity.price_id + + @pricelists[account_activity.price_id] = account_activity.price + end + end + end +end diff --git a/app/models/concerns/registrar/legal_doc.rb b/app/models/concerns/registrar/legal_doc.rb new file mode 100644 index 000000000..2f21f6637 --- /dev/null +++ b/app/models/concerns/registrar/legal_doc.rb @@ -0,0 +1,16 @@ +module Concerns + module Registrar + module LegalDoc + extend ActiveSupport::Concern + + def legaldoc_mandatory? + !legaldoc_not_mandatory? + end + + def legaldoc_not_mandatory? + setting = Setting.legal_document_is_mandatory + legaldoc_optout || !setting + end + end + end +end diff --git a/app/models/concerns/remove_hold.rb b/app/models/concerns/remove_hold.rb new file mode 100644 index 000000000..1da3b5a7f --- /dev/null +++ b/app/models/concerns/remove_hold.rb @@ -0,0 +1,9 @@ +module RemoveHold + extend ActiveSupport::Concern + + def remove_hold(params) + xml = epp_xml.update(name: { value: params[:domain_name] }, + rem: [status: { attrs: { s: 'clientHold' }, value: '' }]) + current_user.request(xml) + end +end diff --git a/app/models/concerns/versions.rb b/app/models/concerns/versions.rb index 77bc484ae..033ebe52a 100644 --- a/app/models/concerns/versions.rb +++ b/app/models/concerns/versions.rb @@ -1,10 +1,17 @@ # Papertrail concerns is mainly tested at country spec module Versions extend ActiveSupport::Concern + WITH_CHILDREN = %w[Domain Contact].freeze included do attr_accessor :version_loader - has_paper_trail class_name: "#{model_name}Version" + + if WITH_CHILDREN.include?(model_name.name) + has_paper_trail versions: { class_name: "#{model_name}Version" }, + meta: { children: :children_log } + else + has_paper_trail versions: { class_name: "#{model_name}Version" } + end # add creator and updator before_create :add_creator @@ -12,23 +19,25 @@ module Versions before_update :add_updator def add_creator - self.creator_str = ::PaperTrail.whodunnit + self.creator_str = ::PaperTrail.request.whodunnit true end def add_updator - self.updator_str = ::PaperTrail.whodunnit + self.updator_str = ::PaperTrail.request.whodunnit true end def creator return nil if creator_str.blank? + creator = user_from_id_role_username creator_str creator.present? ? creator : creator_str end def updator return nil if updator_str.blank? + updator = user_from_id_role_username updator_str updator.present? ? updator : updator_str end @@ -45,25 +54,27 @@ module Versions # callbacks def touch_domain_version - domain.try(:touch_with_version) + domain.try(:touch) end def touch_domains_version - domains.each(&:touch_with_version) + domains.each(&:touch) end end module ClassMethods def all_versions_for(ids, time) - ver_klass = paper_trail_version_class + ver_klass = paper_trail.version_class from_history = ver_klass.where(item_id: ids.to_a). order(:item_id). preceding(time + 1, true). select("distinct on (item_id) #{ver_klass.table_name}.*"). map do |ver| - o = new(ver.object) + valid_columns = ver.item_type.constantize&.column_names + o = new(ver.object&.slice(*valid_columns)) o.version_loader = ver - ver.object_changes.to_h.each { |k, v| o.public_send("#{k}=", v[-1]) } + changes = ver.object_changes.to_h&.slice(*valid_columns) + changes.each { |k, v| o.public_send("#{k}=", v[-1]) } o end not_in_history = where(id: (ids.to_a - from_history.map(&:id))) diff --git a/app/models/concerns/whois_status_populate.rb b/app/models/concerns/whois_status_populate.rb new file mode 100644 index 000000000..616cc7d22 --- /dev/null +++ b/app/models/concerns/whois_status_populate.rb @@ -0,0 +1,15 @@ +module WhoisStatusPopulate + extend ActiveSupport::Concern + + def generate_json(record, domain_status:) + h = HashWithIndifferentAccess.new(name: record.name, status: [domain_status]) + return h if record.json.blank? + + status_arr = (record.json['status'] ||= []) + return record.json if status_arr.include? domain_status + + status_arr.push(domain_status) + record.json['status'] = status_arr + record.json + end +end diff --git a/app/models/concerns/zone/whois_queryable.rb b/app/models/concerns/zone/whois_queryable.rb new file mode 100644 index 000000000..c79700582 --- /dev/null +++ b/app/models/concerns/zone/whois_queryable.rb @@ -0,0 +1,74 @@ +module Concerns + module Zone + module WhoisQueryable + extend ActiveSupport::Concern + + included do + after_save :update_whois_record, if: :subzone? + after_destroy :update_whois_record + end + + def subzone? + origin.include? '.' + end + + def update_whois_record + UpdateWhoisRecordJob.enqueue origin, 'zone' + end + + def generate_data + wr = Whois::Record.find_or_initialize_by(name: origin) + wr.json = generate_json + wr.save + end + + def generate_json + data = {}.with_indifferent_access + [domain_vars, registrar_vars, registrant_vars].each do |h| + data.merge!(h) + end + + data + end + + # 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, + 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 } + end + + def registrar_vars + { 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] } + end + + def contact_vars + { name: Setting.registry_invoice_contact, email: Setting.registry_email, + disclosed_attributes: %w[name email] } + end + + def nameserver_vars + vars = [] + return vars unless ns_records + + parsed_ns = ns_records.gsub("\r", '').gsub("\n", '') + parsed_ns.split("#{origin}. IN NS ").each do |ns| + ns.delete_suffix! '.' + vars << ns if ns.match? Nameserver::HOSTNAME_REGEXP + end + + vars + end + end + end +end diff --git a/app/models/contact.rb b/app/models/contact.rb index 127630ac8..7e9aa75c0 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -1,4 +1,6 @@ -class Contact < ActiveRecord::Base +require 'deserializers/xml/legal_document' + +class Contact < ApplicationRecord include Versions # version/contact_version.rb include EppErrors include UserEvents @@ -6,6 +8,7 @@ class Contact < ActiveRecord::Base include Concerns::Contact::Identical include Concerns::Contact::Disclosable include Concerns::Contact::Archivable + include Concerns::EmailVerifable belongs_to :original, class_name: self.name belongs_to :registrar, required: true @@ -15,21 +18,25 @@ class Contact < ActiveRecord::Base has_many :registrant_domains, class_name: 'Domain', foreign_key: 'registrant_id' has_many :actions, dependent: :destroy - has_paper_trail class_name: "ContactVersion", meta: { children: :children_log } - attr_accessor :legal_document_id alias_attribute :kind, :ident_type alias_attribute :copy_from_id, :original_id # Old attribute name; for PaperTrail accepts_nested_attributes_for :legal_documents + scope :email_verification_failed, lambda { + joins('LEFT JOIN email_address_verifications emv ON contacts.email = emv.email') + .where('success = false and verified_at IS NOT NULL') + } + validates :name, :email, presence: true - validates :street, :city, :zip, :country_code, presence: true, if: 'self.class.address_processing?' + validates :street, :city, :zip, :country_code, presence: true, if: lambda { + self.class.address_processing? + } validates :phone, presence: true, e164: true, phone: true - validates :email, format: /@/ - validates :email, email_format: { message: :invalid }, if: proc { |c| c.email_changed? } + validate :correct_email_format, if: proc { |c| c.will_save_change_to_email? } validates :code, uniqueness: { message: :epp_id_taken }, @@ -38,7 +45,7 @@ class Contact < ActiveRecord::Base validates_associated :identifier validate :validate_html - validate :validate_country_code, if: 'self.class.address_processing?' + validate :validate_country_code, if: -> { self.class.address_processing? } after_initialize do self.status_notes = {} if status_notes.nil? @@ -56,6 +63,9 @@ class Contact < ActiveRecord::Base mapping: [%w[ident code], %w[ident_type type], %w[ident_country_code country_code]] after_save :update_related_whois_records + before_validation :clear_address_modifications, if: -> { !self.class.address_processing? } + + self.ignored_columns = %w[legacy_id legacy_history_id] ORG = 'org' PRIV = 'priv' @@ -203,10 +213,9 @@ class Contact < ActiveRecord::Base end def registrant_user_contacts(registrant_user) - # In Rails 5, can be replaced with a much simpler `or` query method and the raw SQL parts can - # be removed. - from("(#{registrant_user_direct_contacts(registrant_user).to_sql} UNION " \ - "#{registrant_user_indirect_contacts(registrant_user).to_sql}) AS contacts") + registrant_user_direct_contacts(registrant_user) + .or(registrant_user_company_contacts(registrant_user)) + .or(registrant_user_indirect_contacts(registrant_user)) end def registrant_user_direct_contacts(registrant_user) @@ -233,13 +242,22 @@ class Contact < ActiveRecord::Base private - def registrant_user_indirect_contacts(registrant_user) + def registrant_user_company_contacts(registrant_user) ident = registrant_user.companies.collect(&:registration_number) where(ident_type: ORG, ident: ident, ident_country_code: registrant_user.country.alpha2) end + + def registrant_user_indirect_contacts(registrant_user) + company_domains = Domain.registrant_user_indirect_domains(registrant_user) + company_contact_ids = company_domains.map(&:contacts).flatten.collect(&:id) + company_ids = Contact.registrant_user_company_contacts(registrant_user).collect(&:id) + total_ids = (company_contact_ids + company_ids).uniq + + where(id: total_ids) + end end def roid @@ -264,7 +282,7 @@ class Contact < ActiveRecord::Base end def to_s - name || '[no name]' + name end def validate_html @@ -325,7 +343,7 @@ class Contact < ActiveRecord::Base return false end - legal_document_data = Epp::Domain.parse_legal_document_from_frame(frame) + legal_document_data = ::Deserializers::Xml::LegalDocument.new(frame).call if legal_document_data @@ -389,45 +407,65 @@ class Contact < ActiveRecord::Base # if total is smaller than needed, the load more # we also need to sort by valid_to # todo: extract to drapper. Then we can remove Domain#roles - def all_domains(page: nil, per: nil, params: {}) - # compose filter sql - filter_sql = case params[:domain_filter] - when "Registrant".freeze - %Q{select id from domains where registrant_id=#{id}} - when AdminDomainContact.to_s, TechDomainContact.to_s - %Q{select domain_id from domain_contacts where contact_id=#{id} AND type='#{params[:domain_filter]}'} - else - %Q{select domain_id from domain_contacts where contact_id=#{id} UNION select id from domains where registrant_id=#{id}} - end + def all_domains(page: nil, per: nil, params:, requester: nil) + filter_sql = qualified_domain_ids(params[:domain_filter]) # get sorting rules sorts = params.fetch(:sort, {}).first || [] - sort = Domain.column_names.include?(sorts.first) ? sorts.first : "valid_to" - order = {"asc"=>"desc", "desc"=>"asc"}[sorts.second] || "desc" - + sort = %w[name registrar_name valid_to].include?(sorts.first) ? sorts.first : 'valid_to' + order = %w[asc desc].include?(sorts.second) ? sorts.second : 'desc' # fetch domains - domains = Domain.where("domains.id IN (#{filter_sql})") + domains = qualified_domain_name_list(requester, filter_sql) domains = domains.includes(:registrar).page(page).per(per) - if sorts.first == "registrar_name".freeze - # using small rails hack to generate outer join - domains = domains.includes(:registrar).where.not(registrars: {id: nil}).order("registrars.name #{order} NULLS LAST") - else - domains = domains.order("#{sort} #{order} NULLS LAST") - end - - + # using small rails hack to generate outer join + domains = if sorts.first == 'registrar_name'.freeze + domains.includes(:registrar).where.not(registrars: { id: nil }) + .order("registrars.name #{order} NULLS LAST") + else + domains.order("#{sort} #{order} NULLS LAST") + end # adding roles. Need here to make faster sqls domain_c = Hash.new([]) - registrant_domains.where(id: domains.map(&:id)).each{|d| domain_c[d.id] |= ["Registrant".freeze] } - DomainContact.where(contact_id: id, domain_id: domains.map(&:id)).each{|d| domain_c[d.domain_id] |= [d.type] } - domains.each{|d| d.roles = domain_c[d.id].uniq} + registrant_domains.where(id: domains.map(&:id)).each do |d| + domain_c[d.id] |= ['Registrant'.freeze] + end + + DomainContact.where(contact_id: id, domain_id: domains.map(&:id)).each do |d| + domain_c[d.domain_id] |= [d.type] + end + + domains.each { |d| d.roles = domain_c[d.id].uniq } domains end + def qualified_domain_name_list(requester, filter_sql) + return Domain.where('domains.id IN (?)', filter_sql) if requester.blank? + + registrant_user = RegistrantUser.find_or_initialize_by(registrant_ident: + "#{requester.ident_country_code}-#{requester.ident}") + begin + registrant_user.domains.where('domains.id IN (?)', filter_sql) + rescue CompanyRegister::NotAvailableError + registrant_user.direct_domains.where('domains.id IN (?)', filter_sql) + end + end + + def qualified_domain_ids(domain_filter) + registrant_ids = registrant_domains.pluck(:id) + return registrant_ids if domain_filter == 'Registrant' + + if %w[AdminDomainContact TechDomainContact].include? domain_filter + DomainContact.select('domain_id').where(contact_id: id, type: domain_filter) + else + (DomainContact.select('domain_id').where(contact_id: id).pluck(:domain_id) + + registrant_ids).uniq + end + end + def update_prohibited? (statuses & [ CLIENT_UPDATE_PROHIBITED, @@ -454,9 +492,23 @@ class Contact < ActiveRecord::Base ]).present? end + def clear_address_modifications + return unless modifies_address? + + remove_address + end + + def modifies_address? + modified = false + self.class.address_attribute_names.each { |field| modified = true if changes.key?(field) } + + modified + end + def update_related_whois_records # not doing anything if no real changes - return if changes.slice(*(self.class.column_names - ["updated_at", "created_at", "statuses", "status_notes"])).empty? + ignored_columns = %w[updated_at created_at statuses status_notes] + return if saved_changes.slice(*(self.class.column_names - ignored_columns)).empty? names = related_domain_descriptions.keys UpdateWhoisRecordJob.enqueue(names, 'domain') if names.present? @@ -531,4 +583,4 @@ class Contact < ActiveRecord::Base def deletable? !linked? end -end \ No newline at end of file +end diff --git a/app/models/counter.rb b/app/models/counter.rb deleted file mode 100644 index 7d1c2b926..000000000 --- a/app/models/counter.rb +++ /dev/null @@ -1,24 +0,0 @@ -class Counter - def initialize value = 0 - @value = value - end - attr_accessor :value - def method_missing *args, &blk - @value.send(*args, &blk) - end - def to_s - @value.to_s - end - - def now - @value - end - - # pre-increment ".+" when x not present - def next(x = 1) - @value += x - end - def prev(x = 1) - @value -= x - end -end \ No newline at end of file diff --git a/app/models/depp/domain.rb b/app/models/depp/domain.rb index 0c8351c97..3bb3b7473 100644 --- a/app/models/depp/domain.rb +++ b/app/models/depp/domain.rb @@ -1,6 +1,7 @@ module Depp class Domain include ActiveModel::Conversion + include RemoveHold extend ActiveModel::Naming attr_accessor :name, :current_user, :epp_xml @@ -121,16 +122,6 @@ module Depp }, op, Domain.construct_custom_params_hash(params))) end - def confirm_keyrelay(domain_params) - xml = epp_xml.update({ - name: { value: domain_params[:name] } - }, { - add: Domain.create_dnskeys_hash(domain_params) - }) - - current_user.request(xml) - end - def confirm_transfer(domain_params) data = current_user.request(epp_xml.info(name: { value: domain_params[:name] })) pw = data.css('pw').text diff --git a/app/models/depp/keyrelay.rb b/app/models/depp/keyrelay.rb deleted file mode 100644 index a528bab2f..000000000 --- a/app/models/depp/keyrelay.rb +++ /dev/null @@ -1,45 +0,0 @@ -module Depp - class Keyrelay - attr_accessor :current_user, :epp_xml - - def initialize(args = {}) - self.current_user = args[:current_user] - self.epp_xml = EppXml::Keyrelay.new(cl_trid_prefix: current_user.tag) - end - - def keyrelay(params) - custom_params = {} - if params[:legal_document].present? - type = params[:legal_document].original_filename.split('.').last.downcase - custom_params = { - _anonymus: [ - legalDocument: { value: Base64.encode64(params[:legal_document].read), attrs: { type: type } } - ] - } - end - - xml = epp_xml.keyrelay({ - name: { value: params['domain_name'] }, - keyData: { - flags: { value: params['key_data_flags'] }, - protocol: { value: params['key_data_protocol'] }, - alg: { value: params['key_data_alg'] }, - pubKey: { value: params['key_data_public_key'] } - }, - authInfo: { - pw: { value: params['password'] } - }, - expiry: expiry(params['expiry']) - }, custom_params) - - current_user.request(xml) - end - - def expiry(value) - ISO8601::Duration.new(value) - { relative: { value: value } } - rescue => _e - { absolute: { value: value } } - end - end -end diff --git a/app/models/directo.rb b/app/models/directo.rb index f062912f9..a4af6c134 100644 --- a/app/models/directo.rb +++ b/app/models/directo.rb @@ -1,196 +1,3 @@ -class Directo < ActiveRecord::Base - DOMAIN_TO_PRODUCT = {"ee" => "01EE", "com.ee" => "02COM", "pri.ee" => "03PRI", "fie.ee"=>"04FIE", "med.ee" => "05MED"}.freeze +class Directo < ApplicationRecord belongs_to :item, polymorphic: true - - def self.send_receipts - new_trans = Invoice.where(in_directo: false).non_cancelled - total = new_trans.count - counter = 0 - Rails.logger.info("[DIRECTO] Will try to send #{total} invoices") - - new_trans.find_in_batches(batch_size: 10).each do |group| - mappers = {} # need them as no direct connection between invoice - builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml| - xml.invoices { - group.each do |invoice| - - if invoice.account_activity.nil? || invoice.account_activity.bank_transaction.nil? || - invoice.account_activity.bank_transaction.sum.nil? || invoice.account_activity.bank_transaction.sum != invoice.total - Rails.logger.info("[DIRECTO] Invoice #{invoice.number} has been skipped") - next - end - counter += 1 - - num = invoice.number - mappers[num] = invoice - xml.invoice( - "SalesAgent" => Setting.directo_sales_agent, - "Number" => num, - "InvoiceDate" => invoice.issue_date.strftime("%Y-%m-%d"), - "PaymentTerm" => Setting.directo_receipt_payment_term, - "Currency" => invoice.currency, - "CustomerCode"=> invoice.buyer.accounting_customer_code - ){ - xml.line( - "ProductID" => Setting.directo_receipt_product_name, - "Quantity" => 1, - "UnitPriceWoVAT" => ActionController::Base.helpers.number_with_precision(invoice.subtotal, precision: 2, separator: "."), - "ProductName" => invoice.order - ) - } - end - } - end - - data = builder.to_xml.gsub("\n",'') - Rails.logger.info("[Directo] XML request: #{data}") - response = RestClient::Request.execute(url: ENV['directo_invoice_url'], method: :post, payload: {put: "1", what: "invoice", xmldata: data}, verify_ssl: false) - Rails.logger.info("[Directo] Directo responded with code: #{response.code}, body: #{response.body}") - dump_result_to_db(mappers, response.to_s) - end - - STDOUT << "#{Time.zone.now.utc} - Directo receipts sending finished. #{counter} of #{total} are sent\n" - end - - def self.dump_result_to_db mappers, xml - Nokogiri::XML(xml).css("Result").each do |res| - obj = mappers[res.attributes["docid"].value.to_i] - obj.directo_records.create!(response: res.as_json.to_h, invoice_number: obj.number) - obj.update_columns(in_directo: true) - Rails.logger.info("[DIRECTO] Invoice #{res.attributes["docid"].value} was pushed and return is #{res.as_json.to_h.inspect}") - end - end - - - def self.send_monthly_invoices(debug: false) - I18n.locale = :et - month = Time.now - 1.month - invoices_until = month.end_of_month - date_format = "%Y-%m-%d" - invoice_counter= Counter.new - - min_directo = Setting.directo_monthly_number_min.presence.try(:to_i) - max_directo = Setting.directo_monthly_number_max.presence.try(:to_i) - last_directo = [Setting.directo_monthly_number_last.presence.try(:to_i), min_directo].compact.max || 0 - if max_directo && max_directo <= last_directo - raise "Directo counter is out of period (max allowed number is smaller than last counter number)" - end - - directo_next = last_directo - Registrar.where.not(test_registrar: true).find_each do |registrar| - unless registrar.cash_account - Rails.logger.info("[DIRECTO] Monthly invoice for registrar #{registrar.id} has been skipped as it doesn't has cash_account") - next - end - counter = Counter.new(1) - items = {} - registrar_activities = AccountActivity.where(account_id: registrar.account_ids).where("created_at BETWEEN ? AND ?",month.beginning_of_month, month.end_of_month) - - # adding domains items - registrar_activities.where(activity_type: [AccountActivity::CREATE, AccountActivity::RENEW]).each do |activity| - price = load_price(activity) - - if price.duration.include?('year') - price.duration.to_i.times do |i| - year = i+1 - hash = { - "ProductID" => DOMAIN_TO_PRODUCT[price.zone_name], - "Unit" => "tk", - "ProductName" => ".#{price.zone_name} registreerimine: #{price.duration.to_i} aasta#{price.duration.to_i > 1 ? 't' : ''}", - "UnitPriceWoVAT" => price.price.amount / price.duration.to_i - } - hash["StartDate"] = (activity.created_at + (year-1).year).end_of_month.strftime(date_format) if year > 1 - hash["EndDate"] = (activity.created_at + (year-1).year + 1).end_of_month.strftime(date_format) if year > 1 - - if items.has_key?(hash) - items[hash]["Quantity"] += 1 - else - items[hash] = { "RN" => counter.next, "RR" => counter.now - i, "Quantity" => 1 } - end - end - else - 1.times do |i| - quantity = price.account_activities - .where(account_id: registrar.account_ids) - .where(created_at: month.beginning_of_month..month.end_of_month) - .where(activity_type: [AccountActivity::CREATE, AccountActivity::RENEW]) - .count - - hash = { - "ProductID" => DOMAIN_TO_PRODUCT[price.zone_name], - "Unit" => "tk", - "ProductName" => ".#{price.zone_name} registreerimine: #{price.duration.to_i} kuud", - "UnitPriceWoVAT" => price.price.amount, - } - - if items.has_key?(hash) - #items[hash]["Quantity"] += 1 - else - items[hash] = { "RN" => counter.next, "RR" => counter.now - i, "Quantity" => quantity } - end - end - end - - - end - - #adding prepaiments - if items.any? - total = 0 - items.each{ |key, val| total += val["Quantity"] * key["UnitPriceWoVAT"] } - hash = {"ProductID" => Setting.directo_receipt_product_name, "Unit" => "tk", "ProductName" => "Domeenide ettemaks", "UnitPriceWoVAT"=>total} - items[hash] = {"RN"=>counter.next, "RR" => counter.now, "Quantity"=> -1} - end - - # generating XML - if items.any? - directo_next += 1 - invoice_counter.next - - builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml| - xml.invoices{ - xml.invoice("Number" =>directo_next, - "InvoiceDate" =>invoices_until.strftime(date_format), - "PaymentTerm" =>Setting.directo_receipt_payment_term, - "CustomerCode"=>registrar.accounting_customer_code, - "Language" =>"", - "Currency" =>registrar_activities.first.currency, - "SalesAgent" =>Setting.directo_sales_agent){ - xml.line("RN" => 1, "RR"=>1, "ProductName"=> "Domeenide registreerimine - #{I18n.l(invoices_until, format: "%B %Y").titleize}") - items.each do |line, val| - xml.line(val.merge(line)) - end - } - } - end - - data = builder.to_xml.gsub("\n",'') - Rails.logger.info("[Directo] XML request: #{data}") - - if debug - STDOUT << "#{Time.zone.now.utc} - Directo xml had to be sent #{data}\n" - else - response = RestClient::Request.execute(url: ENV['directo_invoice_url'], method: :post, payload: {put: "1", what: "invoice", xmldata: data}, verify_ssl: false) - Rails.logger.info("[Directo] Directo responded with code: #{response.code}, body: #{response.body}") - response = response.to_s - - Setting.directo_monthly_number_last = directo_next - Nokogiri::XML(response).css("Result").each do |res| - Directo.create!(request: data, response: res.as_json.to_h, invoice_number: directo_next) - Rails.logger.info("[DIRECTO] Invoice #{res.attributes["docid"].value} was pushed and return is #{res.as_json.to_h.inspect}") - end - end - else - Rails.logger.info("[DIRECTO] Registrar #{registrar.id} has nothing to be sent to Directo") - end - - end - STDOUT << "#{Time.zone.now.utc} - Directo invoices sending finished. #{invoice_counter.now} are sent\n" - end - - def self.load_price(account_activity) - @pricelists ||= {} - return @pricelists[account_activity.price_id] if @pricelists.has_key?(account_activity.price_id) - @pricelists[account_activity.price_id] = account_activity.price - end end diff --git a/app/models/dispute.rb b/app/models/dispute.rb new file mode 100644 index 000000000..45ff27274 --- /dev/null +++ b/app/models/dispute.rb @@ -0,0 +1,133 @@ +class Dispute < ApplicationRecord + include WhoisStatusPopulate + validates :domain_name, :password, :starts_at, :expires_at, presence: true + before_validation :fill_empty_passwords, :set_expiry_date + validate :validate_domain_name_format + validate :validate_domain_name_period_uniqueness + validate :validate_start_date + + before_save :set_expiry_date, :sync_reserved_password, :generate_data + after_destroy :remove_data + + scope :expired, -> { where('expires_at < ?', Time.zone.today) } + scope :active, lambda { + where('starts_at <= ? AND expires_at >= ? AND closed IS NULL', Time.zone.today, Time.zone.today) + } + scope :closed, -> { where.not(closed: nil) } + + attr_readonly :domain_name + + def domain + Domain.find_by(name: domain_name) + end + + def self.close_by_domain(domain_name) + dispute = Dispute.active.find_by(domain_name: domain_name) + return false unless dispute + + dispute.close(initiator: 'Registrant') + end + + def self.valid_auth?(domain_name, password) + Dispute.active.find_by(domain_name: domain_name, password: password).present? + end + + def set_expiry_date + return if starts_at.blank? + + self.expires_at = starts_at + Setting.dispute_period_in_months.months + end + + def generate_password + self.password = SecureRandom.hex + end + + def generate_data + return if starts_at > Time.zone.today || expires_at < Time.zone.today + + domain&.mark_as_disputed + return if domain + + wr = Whois::Record.find_or_initialize_by(name: domain_name) + wr.json = @json = generate_json(wr, domain_status: 'disputed') + wr.save + end + + def close(initiator: 'Unknown') + return false unless update(closed: Time.zone.now, initiator: initiator) + return if Dispute.active.where(domain_name: domain_name).any? + + domain&.unmark_as_disputed + return true if domain + + forward_to_auction_if_possible + end + + def forward_to_auction_if_possible + domain = DNS::DomainName.new(domain_name) + if domain.available? && domain.auctionable? + domain.sell_at_auction + return true + end + + whois_record = Whois::Record.find_by(name: domain_name) + remove_whois_data(whois_record) + end + + def remove_whois_data(record) + return true unless record + + record.json['status'] = record.json['status'].delete_if { |status| status == 'disputed' } + record.destroy && return if record.json['status'].blank? + + record.save + end + + def remove_data + UpdateWhoisRecordJob.enqueue domain_name, 'disputed' + end + + def fill_empty_passwords + generate_password if password.blank? + end + + def sync_reserved_password + reserved_domain = ReservedDomain.find_by(name: domain_name) + generate_password if password.blank? + + unless reserved_domain.nil? + reserved_domain.password = password + reserved_domain.save! + end + + generate_data + end + + private + + def validate_start_date + return if starts_at.nil? + + errors.add(:starts_at, :future) if starts_at.future? + end + + def validate_domain_name_format + return unless domain_name + + zone = domain_name.reverse.rpartition('.').map(&:reverse).reverse.last + supported_zone = DNS::Zone.origins.include?(zone) + + errors.add(:domain_name, :unsupported_zone) unless supported_zone + end + + def validate_domain_name_period_uniqueness + existing_dispute = Dispute.unscoped.where(domain_name: domain_name, closed: nil) + .where('expires_at >= ?', starts_at) + + existing_dispute = existing_dispute.where.not(id: id) unless new_record? + + return unless existing_dispute.any? + + errors.add(:starts_at, 'Dispute already exists for this domain at given timeframe') + end +end diff --git a/app/models/dns/domain_name.rb b/app/models/dns/domain_name.rb index d2ca9fa50..c1af4d5e7 100644 --- a/app/models/dns/domain_name.rb +++ b/app/models/dns/domain_name.rb @@ -60,13 +60,18 @@ module DNS end def blocked? - BlockedDomain.where(name: name).any? + BlockedDomain.where(name: name).any? || + BlockedDomain.where(name: SimpleIDN.to_unicode(name)).any? end def reserved? ReservedDomain.where(name: name).any? end + def disputed? + Dispute.active.where(domain_name: name).any? + end + def auctionable? !not_auctionable? end @@ -80,7 +85,7 @@ module DNS attr_reader :name def not_auctionable? - blocked? || reserved? + blocked? || reserved? || disputed? end def zone_with_same_origin? diff --git a/app/models/dns/zone.rb b/app/models/dns/zone.rb index a63d9b280..31749d952 100644 --- a/app/models/dns/zone.rb +++ b/app/models/dns/zone.rb @@ -1,11 +1,14 @@ +# frozen_string_literal: true + module DNS - class Zone < ActiveRecord::Base + class Zone < ApplicationRecord validates :origin, :ttl, :refresh, :retry, :expire, :minimum_ttl, :email, :master_nameserver, presence: true validates :ttl, :refresh, :retry, :expire, :minimum_ttl, numericality: { only_integer: true } validates :origin, uniqueness: true + include Concerns::Zone::WhoisQueryable before_destroy do - !used? + throw(:abort) if used? end def self.generate_zonefiles diff --git a/app/models/dnskey.rb b/app/models/dnskey.rb index 02b43d729..c0f3f7491 100644 --- a/app/models/dnskey.rb +++ b/app/models/dnskey.rb @@ -1,4 +1,4 @@ -class Dnskey < ActiveRecord::Base +class Dnskey < ApplicationRecord include Versions # version/dnskey_version.rb include EppErrors @@ -9,10 +9,16 @@ class Dnskey < ActiveRecord::Base validate :validate_protocol validate :validate_flags - before_save -> { generate_digest if public_key_changed? && !ds_digest_changed? } + before_save lambda { + generate_digest if will_save_change_to_public_key? && !will_save_change_to_ds_digest? + } before_save lambda { - if (public_key_changed? || flags_changed? || alg_changed? || protocol_changed?) && !ds_key_tag_changed? + if (will_save_change_to_public_key? || + will_save_change_to_flags? || + will_save_change_to_alg? || + will_save_change_to_protocol?) && + !will_save_change_to_ds_key_tag? generate_ds_key_tag end } @@ -22,6 +28,8 @@ class Dnskey < ActiveRecord::Base FLAGS = %w(0 256 257) # 256 = ZSK, 257 = KSK DS_DIGEST_TYPE = [1,2] + self.ignored_columns = %w[legacy_domain_id] + def epp_code_map { '2005' => [ diff --git a/app/models/domain.rb b/app/models/domain.rb index beef862e3..c60d11f3f 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -1,4 +1,4 @@ -class Domain < ActiveRecord::Base +class Domain < ApplicationRecord include UserEvents include Versions # version/domain_version.rb include Concerns::Domain::Expirable @@ -9,8 +9,7 @@ class Domain < ActiveRecord::Base include Concerns::Domain::Transferable include Concerns::Domain::RegistryLockable include Concerns::Domain::Releasable - - has_paper_trail class_name: "DomainVersion", meta: { children: :children_log } + include Concerns::Domain::Disputable attr_accessor :roles @@ -51,13 +50,13 @@ class Domain < ActiveRecord::Base has_many :dnskeys, dependent: :destroy - has_many :keyrelays has_one :whois_record # destroyment will be done in after_commit accepts_nested_attributes_for :dnskeys, allow_destroy: true has_many :legal_documents, as: :documentable accepts_nested_attributes_for :legal_documents, reject_if: proc { |attrs| attrs[:body].blank? } + has_many :registrant_verifications, dependent: :destroy after_initialize do self.pending_json = {} if pending_json.blank? @@ -73,12 +72,13 @@ class Domain < ActiveRecord::Base before_update :manage_statuses def manage_statuses - return unless registrant_id_changed? # rollback has not yet happened + return unless will_save_change_to_registrant_id? # rollback has not yet happened + pending_update! if registrant_verification_asked? true end - after_commit :update_whois_record, unless: 'domain_name.at_auction?' + after_commit :update_whois_record, unless: -> { domain_name.at_auction? } after_create :update_reserved_domains def update_reserved_domains @@ -89,8 +89,8 @@ class Domain < ActiveRecord::Base validates :puny_label, length: { maximum: 63 } validates :period, presence: true, numericality: { only_integer: true } validates :transfer_code, presence: true - validate :validate_reservation + def validate_reservation return if persisted? || !in_reserved_list? @@ -100,6 +100,7 @@ class Domain < ActiveRecord::Base end return if ReservedDomain.pw_for(name) == reserved_pw + errors.add(:base, :invalid_auth_information_reserved) end @@ -116,12 +117,15 @@ class Domain < ActiveRecord::Base attr_accessor :is_admin - validate :check_permissions, :unless => :is_admin - def check_permissions - return unless force_delete_scheduled? - errors.add(:base, I18n.t(:object_status_prohibits_operation)) - false - end + # Removed to comply new ForceDelete procedure + # at https://github.com/internetee/registry/issues/1428#issuecomment-570561967 + # + # validate :check_permissions, :unless => :is_admin + # def check_permissions + # return unless force_delete_scheduled? + # errors.add(:base, I18n.t(:object_status_prohibits_operation)) + # false + # end validates :nameservers, domain_nameserver: { min: -> { Setting.ns_min_count }, @@ -170,6 +174,8 @@ class Domain < ActiveRecord::Base attr_accessor :registrant_typeahead, :update_me, :epp_pending_update, :epp_pending_delete, :reserved_pw + self.ignored_columns = %w[legacy_id legacy_registrar_id legacy_registrant_id] + def subordinate_nameservers nameservers.select { |x| x.hostname.end_with?(name) } end @@ -192,17 +198,14 @@ class Domain < ActiveRecord::Base end def registrant_user_domains(registrant_user) - # In Rails 5, can be replaced with a much simpler `or` query method and the raw SQL parts can - # be removed. from( "(#{registrant_user_domains_by_registrant(registrant_user).to_sql} UNION " \ + "#{registrant_user_indirect_domains(registrant_user).to_sql} UNION " \ "#{registrant_user_domains_by_contact(registrant_user).to_sql}) AS domains" ) end def registrant_user_direct_domains(registrant_user) - # In Rails 5, can be replaced with a much simpler `or` query method and the raw SQL parts can - # be removed. from( "(#{registrant_user_direct_domains_by_registrant(registrant_user).to_sql} UNION " \ "#{registrant_user_direct_domains_by_contact(registrant_user).to_sql}) AS domains" @@ -210,14 +213,20 @@ class Domain < ActiveRecord::Base end def registrant_user_administered_domains(registrant_user) - # In Rails 5, can be replaced with a much simpler `or` query method and the raw SQL parts can - # be removed. from( "(#{registrant_user_domains_by_registrant(registrant_user).to_sql} UNION " \ "#{registrant_user_domains_by_admin_contact(registrant_user).to_sql}) AS domains" ) end + def registrant_user_indirect_domains(registrant_user) + companies = Contact.registrant_user_company_contacts(registrant_user) + from( + "(#{registrant_user_company_registrant(companies).to_sql} UNION "\ + "#{registrant_user_domains_company(companies).to_sql}) AS domains" + ) + end + private def registrant_user_domains_by_registrant(registrant_user) @@ -230,7 +239,7 @@ class Domain < ActiveRecord::Base def registrant_user_domains_by_admin_contact(registrant_user) joins(:domain_contacts).where(domain_contacts: { contact_id: registrant_user.contacts, - type: [AdminDomainContact] }) + type: [AdminDomainContact.name] }) end def registrant_user_direct_domains_by_registrant(registrant_user) @@ -240,11 +249,19 @@ class Domain < ActiveRecord::Base def registrant_user_direct_domains_by_contact(registrant_user) joins(:domain_contacts).where(domain_contacts: { contact_id: registrant_user.direct_contacts }) end + + def registrant_user_company_registrant(companies) + where(registrant: companies) + end + + def registrant_user_domains_company(companies) + joins(:domain_contacts).where(domain_contacts: { contact: companies }) + end end def name=(value) - value.strip! - value.downcase! + value&.strip! + value&.downcase! self[:name] = SimpleIDN.to_unicode(value) self[:name_puny] = SimpleIDN.to_ascii(value) self[:name_dirty] = value @@ -284,20 +301,23 @@ class Domain < ActiveRecord::Base def server_holdable? return false if statuses.include?(DomainStatus::SERVER_HOLD) return false if statuses.include?(DomainStatus::SERVER_MANUAL_INZONE) + true end def renewable? - if Setting.days_to_renew_domain_before_expire != 0 - # if you can renew domain at days_to_renew before domain expiration - if (expire_time.to_date - Date.today) + 1 > Setting.days_to_renew_domain_before_expire - return false - end + blocking_statuses = [DomainStatus::DELETE_CANDIDATE, DomainStatus::PENDING_RENEW, + DomainStatus::PENDING_TRANSFER, DomainStatus::DISPUTED, + DomainStatus::PENDING_UPDATE, DomainStatus::PENDING_DELETE, + DomainStatus::PENDING_DELETE_CONFIRMATION] + return false if statuses.include_any? blocking_statuses + return true unless Setting.days_to_renew_domain_before_expire != 0 + + # if you can renew domain at days_to_renew before domain expiration + if (expire_time.to_date - Time.zone.today) + 1 > Setting.days_to_renew_domain_before_expire + return false end - return false if statuses.include_any?(DomainStatus::DELETE_CANDIDATE, DomainStatus::PENDING_RENEW, - DomainStatus::PENDING_TRANSFER, DomainStatus::PENDING_DELETE, - DomainStatus::PENDING_UPDATE, DomainStatus::PENDING_DELETE_CONFIRMATION) true end @@ -487,9 +507,9 @@ class Domain < ActiveRecord::Base self.delete_date = nil when DomainStatus::SERVER_MANUAL_INZONE # removal causes server hold to set self.outzone_at = Time.zone.now if force_delete_scheduled? - when DomainStatus::DomainStatus::EXPIRED # removal causes server hold to set + when DomainStatus::EXPIRED # removal causes server hold to set self.outzone_at = self.expire_time + 15.day - when DomainStatus::DomainStatus::SERVER_HOLD # removal causes server hold to set + when DomainStatus::SERVER_HOLD # removal causes server hold to set self.outzone_at = nil end end @@ -548,6 +568,8 @@ class Domain < ActiveRecord::Base activate if nameservers.reject(&:marked_for_destruction?).size >= Setting.ns_min_count end + cancel_force_delete if force_delete_scheduled? && will_save_change_to_registrant_id? + if statuses.empty? && valid? statuses << DomainStatus::OK elsif (statuses.length > 1 && active?) || !valid? @@ -586,6 +608,15 @@ class Domain < ActiveRecord::Base (admin_contacts.emails + [registrant.email]).uniq end + def force_delete_contact_emails + (primary_contact_emails + tech_contacts.pluck(:email) + + ["info@#{name}", "#{prepared_domain_name}@#{name}"]).uniq + end + + def prepared_domain_name + name.split('.')&.first + end + def new_registrant_email pending_json['new_registrant_email'] end diff --git a/app/models/domain_contact.rb b/app/models/domain_contact.rb index b433cd3dc..910f4e445 100644 --- a/app/models/domain_contact.rb +++ b/app/models/domain_contact.rb @@ -1,4 +1,4 @@ -class DomainContact < ActiveRecord::Base +class DomainContact < ApplicationRecord # STI: tech_domain_contact # STI: admin_domain_contact include Versions # version/domain_contact_version.rb @@ -8,6 +8,8 @@ class DomainContact < ActiveRecord::Base attr_accessor :value_typeahead + self.ignored_columns = %w[legacy_domain_id legacy_contact_id] + def epp_code_map { '2302' => [ diff --git a/app/models/domain_cron.rb b/app/models/domain_cron.rb index 578538e17..ad64456ca 100644 --- a/app/models/domain_cron.rb +++ b/app/models/domain_cron.rb @@ -1,9 +1,12 @@ class DomainCron + include Concerns::Job::ForceDelete + include Concerns::Job::ForceDeleteLogging + include Concerns::Job::ForceDeleteNotify def self.clean_expired_pendings STDOUT << "#{Time.zone.now.utc} - Clean expired domain pendings\n" unless Rails.env.test? - ::PaperTrail.whodunnit = "cron - #{__method__}" + ::PaperTrail.request.whodunnit = "cron - #{__method__}" expire_at = Setting.expire_pending_confirmation.hours.ago count = 0 expired_pending_domains = Domain.where('registrant_verification_asked_at <= ?', expire_at) @@ -35,7 +38,7 @@ class DomainCron end def self.start_expire_period - ::PaperTrail.whodunnit = "cron - #{__method__}" + ::PaperTrail.request.whodunnit = "cron - #{__method__}" domains = Domain.expired marked = 0 real = 0 @@ -61,7 +64,7 @@ class DomainCron def self.start_redemption_grace_period STDOUT << "#{Time.zone.now.utc} - Setting server_hold to domains\n" unless Rails.env.test? - ::PaperTrail.whodunnit = "cron - #{__method__}" + ::PaperTrail.request.whodunnit = "cron - #{__method__}" domains = Domain.outzone_candidates marked = 0 diff --git a/app/models/domain_status.rb b/app/models/domain_status.rb index 151ecb0ee..bf0ae2a51 100644 --- a/app/models/domain_status.rb +++ b/app/models/domain_status.rb @@ -1,7 +1,7 @@ -class DomainStatus < ActiveRecord::Base - include Versions # version/domain_status_version.rb - include EppErrors +# frozen_string_literal: true +class DomainStatus < ApplicationRecord + include EppErrors belongs_to :domain # Requests to delete the object MUST be rejected. @@ -72,6 +72,7 @@ class DomainStatus < ActiveRecord::Base FORCE_DELETE = 'serverForceDelete' DELETE_CANDIDATE = 'deleteCandidate' EXPIRED = 'expired' + DISPUTED = 'disputed' STATUSES = [ CLIENT_DELETE_PROHIBITED, SERVER_DELETE_PROHIBITED, CLIENT_HOLD, SERVER_HOLD, @@ -80,19 +81,19 @@ class DomainStatus < ActiveRecord::Base INACTIVE, OK, PENDING_CREATE, PENDING_DELETE, PENDING_DELETE_CONFIRMATION, PENDING_RENEW, PENDING_TRANSFER, PENDING_UPDATE, SERVER_MANUAL_INZONE, SERVER_REGISTRANT_CHANGE_PROHIBITED, SERVER_ADMIN_CHANGE_PROHIBITED, SERVER_TECH_CHANGE_PROHIBITED, FORCE_DELETE, - DELETE_CANDIDATE, EXPIRED - ] + DELETE_CANDIDATE, EXPIRED, DISPUTED + ].freeze CLIENT_STATUSES = [ CLIENT_DELETE_PROHIBITED, CLIENT_HOLD, CLIENT_RENEW_PROHIBITED, CLIENT_TRANSFER_PROHIBITED, CLIENT_UPDATE_PROHIBITED - ] + ].freeze SERVER_STATUSES = [ SERVER_DELETE_PROHIBITED, SERVER_HOLD, SERVER_RENEW_PROHIBITED, SERVER_TRANSFER_PROHIBITED, SERVER_UPDATE_PROHIBITED, SERVER_MANUAL_INZONE, SERVER_REGISTRANT_CHANGE_PROHIBITED, SERVER_ADMIN_CHANGE_PROHIBITED, SERVER_TECH_CHANGE_PROHIBITED - ] + ].freeze UPDATE_PROHIBIT_STATES = [ DomainStatus::PENDING_DELETE_CONFIRMATION, diff --git a/app/models/domain_transfer.rb b/app/models/domain_transfer.rb index 91cdb2d67..02ab2bc88 100644 --- a/app/models/domain_transfer.rb +++ b/app/models/domain_transfer.rb @@ -1,4 +1,4 @@ -class DomainTransfer < ActiveRecord::Base +class DomainTransfer < ApplicationRecord belongs_to :domain belongs_to :old_registrar, class_name: 'Registrar' diff --git a/app/models/email_address_verification.rb b/app/models/email_address_verification.rb new file mode 100644 index 000000000..2fe7c0dbe --- /dev/null +++ b/app/models/email_address_verification.rb @@ -0,0 +1,56 @@ +class EmailAddressVerification < ApplicationRecord + RECENTLY_VERIFIED_PERIOD = 1.month + + scope :not_verified_recently, lambda { + where('verified_at IS NULL or verified_at < ?', verification_period) + } + + scope :verified_recently, lambda { + where('verified_at IS NOT NULL and verified_at >= ?', verification_period).where(success: true) + } + + scope :verification_failed, lambda { + where.not(verified_at: nil).where(success: false) + } + + scope :by_domain, ->(domain_name) { where(domain: domain_name) } + + def recently_verified? + verified_at.present? && + verified_at > verification_period + end + + def verification_period + self.class.verification_period + end + + def self.verification_period + Time.zone.now - RECENTLY_VERIFIED_PERIOD + end + + def not_verified? + verified_at.blank? && !success + end + + def failed? + verified_at.present? && !success + end + + def verified? + success + end + + def verify + validation_request = Truemail.validate(email) + + if validation_request.result.success + update(verified_at: Time.zone.now, + success: true) + else + update(verified_at: Time.zone.now, + success: false) + end + + validation_request.result + end +end diff --git a/app/models/epp/contact.rb b/app/models/epp/contact.rb index a33e55a0e..6867b037d 100644 --- a/app/models/epp/contact.rb +++ b/app/models/epp/contact.rb @@ -1,3 +1,7 @@ +require 'deserializers/xml/legal_document' +require 'deserializers/xml/ident' +require 'deserializers/xml/contact' + class Epp::Contact < Contact include EppErrors @@ -9,7 +13,7 @@ class Epp::Contact < Contact def manage_permissions return unless update_prohibited? || delete_prohibited? add_epp_error('2304', nil, nil, I18n.t(:object_status_prohibits_operation)) - false + throw(:abort) end class << self @@ -20,26 +24,9 @@ class Epp::Contact < Contact end def attrs_from(frame, new_record: false) - f = frame - at = {}.with_indifferent_access - at[:name] = f.css('postalInfo name').text if f.css('postalInfo name').present? - at[:org_name] = f.css('postalInfo org').text if f.css('postalInfo org').present? - at[:email] = f.css('email').text if f.css('email').present? - at[:fax] = f.css('fax').text if f.css('fax').present? - at[:phone] = f.css('voice').text if f.css('voice').present? - - if address_processing? - at[:city] = f.css('postalInfo addr city').text if f.css('postalInfo addr city').present? - at[:zip] = f.css('postalInfo addr pc').text if f.css('postalInfo addr pc').present? - at[:street] = f.css('postalInfo addr street').text if f.css('postalInfo addr street').present? - at[:state] = f.css('postalInfo addr sp').text if f.css('postalInfo addr sp').present? - at[:country_code] = f.css('postalInfo addr cc').text if f.css('postalInfo addr cc').present? - end - - at[:auth_info] = f.css('authInfo pw').text if f.css('authInfo pw').present? - - - at.merge!(ident_attrs(f.css('ident').first)) if new_record + at = ::Deserializers::Xml::Contact.new(frame).call + ident_attrs = ::Deserializers::Xml::Ident.new(frame).call + at.merge!(ident_attrs) if new_record at end @@ -54,36 +41,6 @@ class Epp::Contact < Contact ) end - def ident_attrs(ident_frame) - return {} unless ident_attr_valid?(ident_frame) - - { - ident: ident_frame.text, - ident_type: ident_frame.attr('type'), - ident_country_code: ident_frame.attr('cc') - } - end - - def ident_attr_valid?(ident_frame) - return false if ident_frame.blank? - return false if ident_frame.try('text').blank? - return false if ident_frame.attr('type').blank? - return false if ident_frame.attr('cc').blank? - - true - end - - def legal_document_attrs(legal_frame) - return [] if legal_frame.blank? - return [] if legal_frame.try('text').blank? - return [] if legal_frame.attr('type').blank? - - [{ - body: legal_frame.text, - document_type: legal_frame.attr('type') - }] - end - def check_availability(codes) codes = [codes] if codes.is_a?(String) @@ -99,10 +56,11 @@ class Epp::Contact < Contact res end - end + delegate :ident_attr_valid?, to: :class + # rubocop:disable Style/SymbolArray def epp_code_map { '2003' => [ # Required parameter missing @@ -120,7 +78,10 @@ class Epp::Contact < Contact [:email, :invalid], [:country_code, :invalid], [:code, :invalid], - [:code, :too_long_contact_code] + [:code, :too_long_contact_code], + [:email, :email_smtp_check_error], + [:email, :email_mx_check_error], + [:email, :email_regex_check_error], ], '2302' => [ # Object exists [:code, :epp_id_taken] @@ -130,95 +91,7 @@ class Epp::Contact < Contact ] } end - - def update_attributes(frame, current_user) - return super if frame.blank? - at = {}.with_indifferent_access - at.deep_merge!(self.class.attrs_from(frame.css('chg'), new_record: false)) - - if Setting.client_status_editing_enabled - at[:statuses] = statuses - statuses_attrs(frame.css('rem'), 'rem') + statuses_attrs(frame.css('add'), 'add') - end - - if doc = attach_legal_document(Epp::Domain.parse_legal_document_from_frame(frame)) - frame.css("legalDocument").first.content = doc.path if doc&.persisted? - self.legal_document_id = doc.id - end - - ident_frame = frame.css('ident').first - - # https://github.com/internetee/registry/issues/576 - if ident_frame - if identifier.valid? - submitted_ident = Ident.new(code: ident_frame.text, - type: ident_frame.attr('type'), - country_code: ident_frame.attr('cc')) - - report_valid_ident_error if submitted_ident != identifier - else - ident_update_attempt = ident_frame.text.present? && (ident_frame.text != ident) - report_ident_update_error if ident_update_attempt - - identifier = Ident.new(code: ident, - type: ident_frame.attr('type'), - country_code: ident_frame.attr('cc')) - - identifier.validate - - self.identifier = identifier - self.ident_updated_at ||= Time.zone.now - end - end - - self.upid = current_user.registrar.id if current_user.registrar - self.up_date = Time.zone.now - - self.attributes = at - - email_changed = email_changed? - old_email = email_was - updated = save - - if updated && email_changed && registrant? - ContactMailer.email_changed(contact: self, old_email: old_email).deliver_now - end - - updated - end - - def statuses_attrs(frame, action) - status_list = status_list_from(frame) - - if action == 'rem' - to_destroy = [] - status_list.each do |status| - if statuses.include?(status) - to_destroy << status - else - add_epp_error('2303', 'status', status, [:contact_statuses, :not_found]) - end - end - - return to_destroy - else - return status_list - end - end - - def status_list_from(frame) - status_list = [] - - frame.css('status').each do |status| - unless Contact::CLIENT_STATUSES.include?(status['s']) - add_epp_error('2303', 'status', status['s'], [:domain_statuses, :not_found]) - next - end - - status_list << status['s'] - end - - status_list - end + # rubocop:enable Style/SymbolArray def attach_legal_document(legal_document_data) return unless legal_document_data @@ -230,7 +103,7 @@ class Epp::Contact < Contact end def add_legal_file_to_new frame - legal_document_data = Epp::Domain.parse_legal_document_from_frame(frame) + legal_document_data = ::Deserializers::Xml::LegalDocument.new(frame).call return unless legal_document_data doc = LegalDocument.create( @@ -243,14 +116,4 @@ class Epp::Contact < Contact frame.css("legalDocument").first.content = doc.path if doc&.persisted? self.legal_document_id = doc.id end - - private - - def report_valid_ident_error - throw :epp_error, { code: '2308', msg: I18n.t('epp.contacts.errors.valid_ident') } - end - - def report_ident_update_error - throw :epp_error, { code: '2308', msg: I18n.t('epp.contacts.errors.ident_update') } - end end diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index ff60efe02..a6fe58c71 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -1,3 +1,5 @@ +require 'deserializers/xml/legal_document' + class Epp::Domain < Domain include EppErrors @@ -9,10 +11,11 @@ class Epp::Domain < Domain def manage_permissions return if is_admin # this bad hack for 109086524, refactor later return true if is_transfer || is_renewal - return unless update_prohibited? || delete_prohibited? + return unless update_prohibited? + stat = (statuses & (DomainStatus::UPDATE_PROHIBIT_STATES + DomainStatus::DELETE_PROHIBIT_STATES)).first add_epp_error('2304', 'status', stat, I18n.t(:object_status_prohibits_operation)) - false + throw(:abort) end after_validation :validate_contacts @@ -23,12 +26,8 @@ class Epp::Domain < Domain active_admins = admin_domain_contacts.select { |x| !x.marked_for_destruction? } active_techs = tech_domain_contacts.select { |x| !x.marked_for_destruction? } - # bullet workaround - ac = active_admins.map { |x| Contact.find(x.contact_id) } - tc = active_techs.map { |x| Contact.find(x.contact_id) } - # validate registrant here as well - ([registrant] + ac + tc).each do |x| + ([registrant] + active_admins + active_techs).each do |x| unless x.valid? add_epp_error('2304', nil, nil, I18n.t(:contact_is_not_valid, value: x.code)) ok = false @@ -56,12 +55,13 @@ class Epp::Domain < Domain def epp_code_map { '2002' => [ # Command use error - [:base, :domain_already_belongs_to_the_querying_registrar] + %i[base domain_already_belongs_to_the_querying_registrar], ], '2003' => [ # Required parameter missing - [:registrant, :blank], - [:registrar, :blank], - [:base, :required_parameter_missing_reserved] + %i[registrant blank], + %i[registrar blank], + %i[base required_parameter_missing_reserved], + %i[base required_parameter_missing_disputed], ], '2004' => [ # Parameter value range error [:dnskeys, :out_of_range, @@ -88,10 +88,11 @@ class Epp::Domain < Domain [:puny_label, :too_long, { obj: 'name', val: name_puny }] ], '2201' => [ # Authorisation error - [:transfer_code, :wrong_pw] + %i[transfer_code wrong_pw], ], '2202' => [ - [:base, :invalid_auth_information_reserved] + %i[base invalid_auth_information_reserved], + %i[base invalid_auth_information_disputed], ], '2302' => [ # Object exists [:name_dirty, :taken, { value: { obj: 'name', val: name_dirty } }], @@ -123,9 +124,8 @@ class Epp::Domain < Domain def attach_default_contacts return if registrant.blank? - regt = Registrant.find(registrant.id) # temp for bullet - tech_contacts << regt if tech_domain_contacts.blank? - admin_contacts << regt if admin_domain_contacts.blank? && !regt.org? + tech_contacts << registrant if tech_domain_contacts.blank? + admin_contacts << registrant if admin_domain_contacts.blank? && !registrant.org? end def attrs_from(frame, current_user, action = nil) @@ -182,14 +182,12 @@ class Epp::Domain < Domain # Adding legal doc to domain and # if something goes wrong - raise Rollback error def add_legal_file_to_new frame - legal_document_data = Epp::Domain.parse_legal_document_from_frame(frame) + legal_document_data = ::Deserializers::Xml::LegalDocument.new(frame).call return unless legal_document_data + return if legal_document_data[:body].starts_with?(ENV['legal_documents_dir']) - doc = LegalDocument.create( - documentable_type: Domain, - document_type: legal_document_data[:type], - body: legal_document_data[:body] - ) + doc = LegalDocument.create(documentable_type: Domain, document_type: legal_document_data[:type], + body: legal_document_data[:body]) self.legal_documents = [doc] frame.css("legalDocument").first.content = doc.path if doc&.persisted? @@ -450,13 +448,16 @@ class Epp::Domain < Domain def update(frame, current_user, verify = true) return super if frame.blank? - check_discarded + if discarded? + add_epp_error('2304', nil, nil, 'Object status prohibits operation') + return + end at = {}.with_indifferent_access at.deep_merge!(attrs_from(frame.css('chg'), current_user, 'chg')) at.deep_merge!(attrs_from(frame.css('rem'), current_user, 'rem')) - if doc = attach_legal_document(Epp::Domain.parse_legal_document_from_frame(frame)) + if doc = attach_legal_document(::Deserializers::Xml::LegalDocument.new(frame).call) frame.css("legalDocument").first.content = doc.path if doc&.persisted? self.legal_document_id = doc.id end @@ -474,13 +475,36 @@ class Epp::Domain < Domain self.up_date = Time.zone.now end - same_registrant_as_current = (registrant.code == frame.css('registrant').text) + registrant_verification_needed = false + # registrant block may not be present, so we need this to rule out false positives + if frame.css('registrant').text.present? + registrant_verification_needed = (registrant.code != frame.css('registrant').text) + end - if !same_registrant_as_current && errors.empty? && verify && + if registrant_verification_needed && disputed? + disputed_pw = frame.css('reserved > pw').text + if disputed_pw.blank? + add_epp_error('2304', nil, nil, 'Required parameter missing; reserved' \ + 'pw element required for dispute domains') + else + dispute = Dispute.active.find_by(domain_name: name, password: disputed_pw) + if dispute + Dispute.close_by_domain(name) + registrant_verification_needed = false # Prevent asking current registrant confirmation + else + add_epp_error('2202', nil, nil, 'Invalid authorization information; '\ + 'invalid reserved>pw value') + end + end + end + + unverified_registrant_params = frame.css('registrant').present? && + frame.css('registrant').attr('verified').to_s.downcase != 'yes' + + if registrant_verification_needed && errors.empty? && verify && Setting.request_confrimation_on_registrant_change_enabled && - frame.css('registrant').present? && - frame.css('registrant').attr('verified').to_s.downcase != 'yes' - registrant_verification_asked!(frame.to_s, current_user.id) + unverified_registrant_params + registrant_verification_asked!(frame.to_s, current_user.id) unless disputed? end errors.empty? && super(at) @@ -517,6 +541,7 @@ class Epp::Domain < Domain def attach_legal_document(legal_document_data) return unless legal_document_data + return if legal_document_data[:body].starts_with?(ENV['legal_documents_dir']) legal_documents.create( document_type: legal_document_data[:type], @@ -525,9 +550,12 @@ class Epp::Domain < Domain end def epp_destroy(frame, user_id) - check_discarded + if discarded? + add_epp_error('2304', nil, nil, 'Object status prohibits operation') + return + end - if doc = attach_legal_document(Epp::Domain.parse_legal_document_from_frame(frame)) + if doc = attach_legal_document(::Deserializers::Xml::LegalDocument.new(frame).call) frame.css("legalDocument").first.content = doc.path if doc&.persisted? end @@ -544,10 +572,10 @@ class Epp::Domain < Domain end def set_pending_delete! - throw :epp_error, { - code: '2304', - msg: I18n.t(:object_status_prohibits_operation) - } unless pending_deletable? + unless pending_deletable? + add_epp_error('2304', nil, nil, I18n.t(:object_status_prohibits_operation)) + return + end self.delete_date = Time.zone.today + Setting.redemption_grace_period.days + 1.day set_pending_delete @@ -590,7 +618,10 @@ class Epp::Domain < Domain ### TRANSFER ### def transfer(frame, action, current_user) - check_discarded + if discarded? + add_epp_error('2106', nil, nil, 'Object is not eligible for transfer') + return + end @is_transfer = true @@ -609,10 +640,8 @@ class Epp::Domain < Domain def query_transfer(frame, current_user) if current_user.registrar == registrar - throw :epp_error, { - code: '2002', - msg: I18n.t(:domain_already_belongs_to_the_querying_registrar) - } + add_epp_error('2002', nil, nil, I18n.t(:domain_already_belongs_to_the_querying_registrar)) + return end transaction do @@ -637,7 +666,7 @@ class Epp::Domain < Domain self.registrar = current_user.registrar end - attach_legal_document(self.class.parse_legal_document_from_frame(frame)) + attach_legal_document(::Deserializers::Xml::LegalDocument.new(frame).call) save!(validate: false) return dt @@ -646,11 +675,10 @@ class Epp::Domain < Domain def approve_transfer(frame, current_user) pt = pending_transfer + if current_user.registrar != pt.old_registrar - throw :epp_error, { - msg: I18n.t('transfer_can_be_approved_only_by_current_registrar'), - code: '2304' - } + add_epp_error('2304', nil, nil, I18n.t('transfer_can_be_approved_only_by_current_registrar')) + return end transaction do @@ -663,7 +691,7 @@ class Epp::Domain < Domain regenerate_transfer_code self.registrar = pt.new_registrar - attach_legal_document(self.class.parse_legal_document_from_frame(frame)) + attach_legal_document(::Deserializers::Xml::LegalDocument.new(frame).call) save!(validate: false) end @@ -672,11 +700,10 @@ class Epp::Domain < Domain def reject_transfer(frame, current_user) pt = pending_transfer + if current_user.registrar != pt.old_registrar - throw :epp_error, { - msg: I18n.t('transfer_can_be_rejected_only_by_current_registrar'), - code: '2304' - } + add_epp_error('2304', nil, nil, I18n.t('transfer_can_be_rejected_only_by_current_registrar')) + return end transaction do @@ -684,59 +711,13 @@ class Epp::Domain < Domain status: DomainTransfer::CLIENT_REJECTED ) - attach_legal_document(self.class.parse_legal_document_from_frame(frame)) + attach_legal_document(::Deserializers::Xml::LegalDocument.new(frame).call) save!(validate: false) end pt end - def keyrelay(parsed_frame, requester) - if registrar == requester - errors.add(:base, :domain_already_belongs_to_the_querying_registrar) and return false - end - - abs_datetime = parsed_frame.css('absolute').text - abs_datetime = DateTime.zone.parse(abs_datetime) if abs_datetime.present? - - transaction do - kr = keyrelays.build( - pa_date: Time.zone.now, - key_data_flags: parsed_frame.css('flags').text, - key_data_protocol: parsed_frame.css('protocol').text, - key_data_alg: parsed_frame.css('alg').text, - key_data_public_key: parsed_frame.css('pubKey').text, - auth_info_pw: parsed_frame.css('pw').text, - expiry_relative: parsed_frame.css('relative').text, - expiry_absolute: abs_datetime, - requester: requester, - accepter: registrar - ) - - legal_document_data = self.class.parse_legal_document_from_frame(parsed_frame) - if legal_document_data - kr.legal_documents.build( - document_type: legal_document_data[:type], - body: legal_document_data[:body] - ) - end - - kr.save - - return false unless valid? - - registrar.notifications.create!( - text: 'Key Relay action completed successfully.', - attached_obj_type: kr.class.to_s, - attached_obj_id: kr.id - ) - end - - true - end - - ### VALIDATIONS ### - def validate_exp_dates(cur_exp_date) begin return if cur_exp_date.to_date == valid_to.to_date @@ -751,6 +732,11 @@ class Epp::Domain < Domain def can_be_deleted? + if disputed? + errors.add(:base, :domain_status_prohibits_operation) + return false + end + begin errors.add(:base, :domain_status_prohibits_operation) return false @@ -774,18 +760,6 @@ class Epp::Domain < Domain p[:unit] end - def parse_legal_document_from_frame(parsed_frame) - ld = parsed_frame.css('legalDocument').first - return nil unless ld - return nil if ld.text.starts_with?(ENV['legal_documents_dir']) # escape reloading - return nil if ld.text.starts_with?('/home/') # escape reloading - - { - body: ld.text, - type: ld['type'] - } - end - def check_availability(domain_names) domain_names = [domain_names] if domain_names.is_a?(String) @@ -814,15 +788,4 @@ class Epp::Domain < Domain result end end - - private - - def check_discarded - if discarded? - throw :epp_error, { - code: '2105', - msg: I18n.t(:object_is_not_eligible_for_renewal), - } - end - end end diff --git a/app/models/epp/response.rb b/app/models/epp/response.rb index c9a5d8bb4..eb61c02a4 100644 --- a/app/models/epp/response.rb +++ b/app/models/epp/response.rb @@ -1,22 +1,27 @@ -module EPP +module Epp class Response - attr_accessor :results + attr_reader :results - def self.from_xml(xml) + def self.xml(xml) xml_doc = Nokogiri::XML(xml) - response = new - result_elements = xml_doc.css('result') + results = [] result_elements.each do |result_element| - response.results << Result.new(result_element[:code].to_s, result_element.text.strip) + code_value = result_element[:code] + code = Result::Code.new(code_value) + results << Result.new(code: code) end - response + new(results: results) end - def initialize - @results = [] + def initialize(results:) + @results = results + end + + def code?(code) + results.any? { |result| result.code == code } end end end diff --git a/app/models/epp/response/result.rb b/app/models/epp/response/result.rb index 5c870c830..2bbf6cbf8 100644 --- a/app/models/epp/response/result.rb +++ b/app/models/epp/response/result.rb @@ -1,27 +1,10 @@ -module EPP +module Epp class Response class Result - CODE_TO_TYPE = { - '1000' => :success, - '1001' => :success_pending, - '1300' => :success_empty_queue, - '1301' => :success_dequeue, - '2001' => :syntax_error, - '2003' => :required_param_missing, - '2005' => :param_syntax_error, - '2308' => :data_management_policy_violation - } + attr_reader :code - attr_accessor :code - attr_accessor :message - - def initialize(code, message) + def initialize(code:) @code = code - @message = message - end - - def self.codes - CODE_TO_TYPE end end end diff --git a/app/models/epp/response/result/code.rb b/app/models/epp/response/result/code.rb new file mode 100644 index 000000000..1be4a3f7c --- /dev/null +++ b/app/models/epp/response/result/code.rb @@ -0,0 +1,89 @@ +module Epp + class Response + class Result + class Code + attr_reader :value + + KEY_TO_VALUE = { + completed_successfully: 1000, + completed_successfully_action_pending: 1001, + completed_without_address: 1100, + completed_successfully_no_messages: 1300, + completed_successfully_ack_to_dequeue: 1301, + completed_successfully_ending_session: 1500, + unknown_command: 2000, + syntax_error: 2001, + use_error: 2002, + required_parameter_missing: 2003, + parameter_value_range_error: 2004, + parameter_value_syntax_error: 2005, + unimplemented: 2101, + billing_failure: 2104, + object_is_not_eligible_for_renewal: 2105, + object_is_not_eligible_for_transfer: 2106, + authorization_error: 2201, + invalid_authorization_information: 2202, + object_does_not_exist: 2303, + object_status_prohibits_operation: 2304, + object_association_prohibits_operation: 2305, + parameter_value_policy_error: 2306, + data_management_policy_violation: 2308, + command_failed: 2400, + authentication_error_server_closing_connection: 2501, + }.freeze + private_constant :KEY_TO_VALUE + + DEFAULT_DESCRIPTIONS = { + 1000 => 'Command completed successfully', + 1001 => 'Command completed successfully; action pending', + 1100 => 'Command completed successfully; Postal address data discarded', + 1300 => 'Command completed successfully; no messages', + 1301 => 'Command completed successfully; ack to dequeue', + 1500 => 'Command completed successfully; ending session', + 2000 => 'Unknown command', + 2001 => 'Command syntax error', + 2002 => 'Command use error', + 2003 => 'Required parameter missing', + 2004 => 'Parameter value range error', + 2005 => 'Parameter value syntax error', + 2101 => 'Unimplemented command', + 2104 => 'Billing failure', + 2105 => 'Object is not eligible for renewal', + 2106 => 'Object is not eligible for transfer', + 2201 => 'Authorization error', + 2202 => 'Invalid authorization information', + 2303 => 'Object does not exist', + 2304 => 'Object status prohibits operation', + 2305 => 'Object association prohibits operation', + 2306 => 'Parameter value policy error', + 2308 => 'Data management policy violation', + 2400 => 'Command failed', + 2501 => 'Authentication error; server closing connection', + }.freeze + private_constant :DEFAULT_DESCRIPTIONS + + def self.codes + KEY_TO_VALUE + end + + def self.default_descriptions + DEFAULT_DESCRIPTIONS + end + + def self.key(key) + new(KEY_TO_VALUE[key]) + end + + def initialize(value) + value = value.to_i + raise ArgumentError, "Invalid value: #{value}" unless KEY_TO_VALUE.value?(value) + @value = value + end + + def ==(other) + value == other.value + end + end + end + end +end diff --git a/app/models/epp_session.rb b/app/models/epp_session.rb index dfd603fc4..6427c503c 100644 --- a/app/models/epp_session.rb +++ b/app/models/epp_session.rb @@ -1,4 +1,4 @@ -class EppSession < ActiveRecord::Base +class EppSession < ApplicationRecord belongs_to :user, required: true validates :session_id, uniqueness: true, presence: true diff --git a/app/models/invoice.rb b/app/models/invoice.rb index a36825848..a130a90ff 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -1,13 +1,14 @@ -class Invoice < ActiveRecord::Base +class Invoice < ApplicationRecord include Versions include Concerns::Invoice::Cancellable include Concerns::Invoice::Payable + include Concerns::Invoice::BookKeeping - belongs_to :seller, class_name: 'Registrar' belongs_to :buyer, class_name: 'Registrar' has_one :account_activity has_many :items, class_name: 'InvoiceItem', dependent: :destroy has_many :directo_records, as: :item, class_name: 'Directo' + has_many :payment_orders accepts_nested_attributes_for :items @@ -36,7 +37,7 @@ class Invoice < ActiveRecord::Base attribute :vat_rate, ::Type::VATRate.new def set_invoice_number - last_no = Invoice.order(number: :desc).where('number IS NOT NULL').limit(1).pluck(:number).first + last_no = Invoice.order(number: :desc).limit(1).pluck(:number).first if last_no && last_no >= Setting.invoice_number_min.to_i self.number = last_no + 1 @@ -48,7 +49,7 @@ class Invoice < ActiveRecord::Base errors.add(:base, I18n.t('failed_to_generate_invoice_invoice_number_limit_reached')) logger.error('INVOICE NUMBER LIMIT REACHED, COULD NOT GENERATE INVOICE') - false + throw(:abort) end def to_s @@ -71,7 +72,7 @@ class Invoice < ActiveRecord::Base Country.new(buyer_country_code) end -# order is used for directo/banklink description + # order is used for directo/banklink description def order "Order nr. #{number}" end @@ -103,6 +104,14 @@ class Invoice < ActiveRecord::Base generator.generate end + def do_not_send_e_invoice? + e_invoice_sent? || cancelled? || paid? + end + + def e_invoice_sent? + e_invoice_sent_at.present? + end + private def apply_default_buyer_vat_no @@ -112,4 +121,4 @@ class Invoice < ActiveRecord::Base def calculate_total self.total = subtotal + vat_amount end -end \ No newline at end of file +end diff --git a/app/models/invoice_item.rb b/app/models/invoice_item.rb index 6efd7b829..ec0c77767 100644 --- a/app/models/invoice_item.rb +++ b/app/models/invoice_item.rb @@ -1,4 +1,4 @@ -class InvoiceItem < ActiveRecord::Base +class InvoiceItem < ApplicationRecord include Versions belongs_to :invoice diff --git a/app/models/keyrelay.rb b/app/models/keyrelay.rb deleted file mode 100644 index ba48991b2..000000000 --- a/app/models/keyrelay.rb +++ /dev/null @@ -1,61 +0,0 @@ -class Keyrelay < ActiveRecord::Base - include Versions # version/keyrelay_version.rb - include EppErrors - - belongs_to :domain - - belongs_to :requester, class_name: 'Registrar' - belongs_to :accepter, class_name: 'Registrar' - - has_many :legal_documents, as: :documentable - - delegate :name, to: :domain, prefix: true - - validates :domain, :key_data_public_key, :key_data_flags, :key_data_protocol, - :key_data_alg, :auth_info_pw, presence: true - validates :expiry_relative, duration_iso8601: true - - validate :validate_expiry_relative_xor_expiry_absolute - - after_save :touch_domain_version - - def epp_code_map - { - '2005' => [ - [:expiry_relative, :unknown_pattern, { value: { obj: 'relative', val: expiry_relative } }] - ], - '2003' => [ - # TODO: Remove only_one_parameter_allowed and other params that are validated in controller? - [:base, :only_one_parameter_allowed, { param_1: 'relative', param_2: 'absolute' }], - [:key_data_public_key, :blank], - [:key_data_flags, :blank], - [:key_data_protocol, :blank], - [:key_data_alg, :blank], - [:auth_info_pw, :blank] - ] - } - end - - def expiry - if expiry_relative.present? - pa_date + ISO8601::Duration.new(expiry_relative).to_seconds - elsif expiry_absolute - expiry_absolute - end - end - - def status - if Time.zone.now > expiry - return 'expired' - else - return 'pending' - end - end - - private - - def validate_expiry_relative_xor_expiry_absolute - return if expiry_relative.blank? ^ expiry_absolute.blank? - errors.add(:base, I18n.t(:only_one_parameter_allowed, param_1: 'relative', param_2: 'absolute')) - end -end diff --git a/app/models/legacy/contact.rb b/app/models/legacy/contact.rb deleted file mode 100644 index 04f8c34a4..000000000 --- a/app/models/legacy/contact.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Legacy - class Contact < Db - self.table_name = :contact - belongs_to :object_registry, foreign_key: :id - belongs_to :object, foreign_key: :id - - has_one :object_state, -> { where('valid_to IS NULL') }, foreign_key: :object_id - end -end diff --git a/app/models/legacy/db.rb b/app/models/legacy/db.rb deleted file mode 100644 index 1cb635b3b..000000000 --- a/app/models/legacy/db.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Legacy - class Db < ActiveRecord::Base - self.abstract_class = true - begin - establish_connection :fred - rescue ActiveRecord::AdapterNotSpecified => e - logger.info "Legacy 'fred' database support is currently disabled because #{e}" - end - - def readonly? - true - end - end -end diff --git a/app/models/legacy/dnskey.rb b/app/models/legacy/dnskey.rb deleted file mode 100644 index 3fa47f48b..000000000 --- a/app/models/legacy/dnskey.rb +++ /dev/null @@ -1,8 +0,0 @@ -module Legacy - class Dnskey < Db - self.table_name = :dnskey - - belongs_to :object_registry, foreign_key: :id - belongs_to :object, foreign_key: :id - end -end diff --git a/app/models/legacy/domain.rb b/app/models/legacy/domain.rb deleted file mode 100644 index d0a05d178..000000000 --- a/app/models/legacy/domain.rb +++ /dev/null @@ -1,16 +0,0 @@ -module Legacy - class Domain < Db - self.table_name = :domain - - belongs_to :object_registry, foreign_key: :id - belongs_to :object, foreign_key: :id - belongs_to :nsset, foreign_key: :nsset - # belongs_to :registrant, foreign_key: :registrant, primary_key: :legacy_id, class_name: '::Contact' - - has_many :object_states, -> { where('valid_to IS NULL') }, foreign_key: :object_id - has_many :dnskeys, foreign_key: :keysetid, primary_key: :keyset - has_many :domain_contact_maps, foreign_key: :domainid - has_many :nsset_contact_maps, foreign_key: :nssetid, primary_key: :nsset - has_many :domain_histories, foreign_key: :id - end -end diff --git a/app/models/legacy/domain_contact_map.rb b/app/models/legacy/domain_contact_map.rb deleted file mode 100644 index 4e645ed7f..000000000 --- a/app/models/legacy/domain_contact_map.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Legacy - class DomainContactMap < Db - self.table_name = :domain_contact_map - - # belongs_to :contact, foreign_key: :contactid, primary_key: :legacy_id, class_name: '::Contact' - end -end diff --git a/app/models/legacy/domain_history.rb b/app/models/legacy/domain_history.rb deleted file mode 100644 index 234585ac3..000000000 --- a/app/models/legacy/domain_history.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Legacy - class DomainHistory < Db - self.table_name = :domain_history - - belongs_to :domain, foreign_key: :id - end -end diff --git a/app/models/legacy/enum_object_state.rb b/app/models/legacy/enum_object_state.rb deleted file mode 100644 index 00a096890..000000000 --- a/app/models/legacy/enum_object_state.rb +++ /dev/null @@ -1,5 +0,0 @@ -module Legacy - class EnumObjectState < Db - self.table_name = :enum_object_states - end -end diff --git a/app/models/legacy/host.rb b/app/models/legacy/host.rb deleted file mode 100644 index 4c4eeab09..000000000 --- a/app/models/legacy/host.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Legacy - class Host < Db - self.table_name = :host - - has_many :host_ipaddr_maps, foreign_key: :hostid - end -end diff --git a/app/models/legacy/host_ipaddr_map.rb b/app/models/legacy/host_ipaddr_map.rb deleted file mode 100644 index a4dc2f14e..000000000 --- a/app/models/legacy/host_ipaddr_map.rb +++ /dev/null @@ -1,5 +0,0 @@ -module Legacy - class HostIpaddrMap < Db - self.table_name = :host_ipaddr_map - end -end diff --git a/app/models/legacy/invoice.rb b/app/models/legacy/invoice.rb deleted file mode 100644 index 15441d89e..000000000 --- a/app/models/legacy/invoice.rb +++ /dev/null @@ -1,5 +0,0 @@ -module Legacy - class Invoice < Db - self.table_name = :invoice - end -end diff --git a/app/models/legacy/nsset.rb b/app/models/legacy/nsset.rb deleted file mode 100644 index 515e9f9a9..000000000 --- a/app/models/legacy/nsset.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Legacy - class Nsset < Db - self.table_name = :nsset - - belongs_to :object, foreign_key: :id - belongs_to :object_registry, foreign_key: :id - has_many :hosts, foreign_key: :nssetid - end -end diff --git a/app/models/legacy/nsset_contact_map.rb b/app/models/legacy/nsset_contact_map.rb deleted file mode 100644 index f7e0a105b..000000000 --- a/app/models/legacy/nsset_contact_map.rb +++ /dev/null @@ -1,5 +0,0 @@ -module Legacy - class NssetContactMap < Db - self.table_name = :nsset_contact_map - end -end diff --git a/app/models/legacy/object.rb b/app/models/legacy/object.rb deleted file mode 100644 index 04218cd09..000000000 --- a/app/models/legacy/object.rb +++ /dev/null @@ -1,11 +0,0 @@ -module Legacy - class Object < Db - self.table_name = :object - belongs_to :registrar, foreign_key: :upid, primary_key: :legacy_id, class_name: '::Registrar' - - def self.instance_method_already_implemented?(method_name) - return true if method_name == 'update' - super - end - end -end diff --git a/app/models/legacy/object_history.rb b/app/models/legacy/object_history.rb deleted file mode 100644 index 35115b4d5..000000000 --- a/app/models/legacy/object_history.rb +++ /dev/null @@ -1,12 +0,0 @@ -module Legacy - class ObjectHistory < Db - self.table_name = :object_history - - belongs_to :object_registry, foreign_key: :historyid - - def self.instance_method_already_implemented?(method_name) - return true if method_name == 'update' - super - end - end -end diff --git a/app/models/legacy/object_registry.rb b/app/models/legacy/object_registry.rb deleted file mode 100644 index 96a6fc6e6..000000000 --- a/app/models/legacy/object_registry.rb +++ /dev/null @@ -1,8 +0,0 @@ -module Legacy - class ObjectRegistry < Db - self.table_name = :object_registry - self.inheritance_column = nil - belongs_to :registrar, foreign_key: :crid, primary_key: :legacy_id, class_name: '::Registrar' - belongs_to :object_history, foreign_key: :historyid - end -end diff --git a/app/models/legacy/object_state.rb b/app/models/legacy/object_state.rb deleted file mode 100644 index 379d4d175..000000000 --- a/app/models/legacy/object_state.rb +++ /dev/null @@ -1,81 +0,0 @@ -module Legacy - class ObjectState < Db - self.table_name = :object_state - - # legacy values. Just for log - # 2 => "serverRenewProhibited", - # 5 => "serverOutzoneManual", - # 6 => "serverInzoneManual", - # 7 => "serverBlocked", - # 8 => "expirationWarning", - # 9 => "expired", - # 10 => "unguarded", - # 11 => "validationWarning1", - # 12 => "validationWarning2", - # 13 => "notValidated", - # 14 => "nssetMissing", - # 15 => "outzone", - # 18 => "serverRegistrantChangeProhibited", - # 19 => "deleteWarning", - # 20 => "outzoneUnguarded", - # 1 => "serverDeleteProhibited", - # 3 => "serverTransferProhibited", - # 4 => "serverUpdateProhibited", - # 16 => "linked", - # 17 => "deleteCandidate", - # 21 => "forceDelete" - - # new values - STATE_NAMES = { - 2 => "serverRenewProhibited", - 5 => "serverHold", - 6 => "serverManualInzone", - # 7 => "serverBlocked", - 9 => "expired", - # 11 => "validationWarning1", - # 13 => "notValidated", - 14 => "inactive", - 15 => "serverHold", - 18 => "serverRegistrantChangeProhibited", - 1 => "serverDeleteProhibited", - 3 => "serverTransferProhibited", - 4 => "serverUpdateProhibited", - 16 => "linked", - 17 => "deleteCandidate", # grupistaatus - 21 => "serverForceDelete" # grupistaatus - }.freeze - - - def name - STATE_NAMES[state_id] - end - - def desc - map = { - 1 => "Delete prohibited", - 2 => "Registration renew prohibited", - 3 => "Sponsoring registrar change prohibited", - 4 => "Update prohibited", - 7 => "Domain blocked", - 8 => "Expires within 30 days", - 9 => "Expired", - 10 => "Domain is 30 days after expiration", - 11 => "Validation of domain expire in 30 days", - 12 => "Validation of domain expire in 15 days", - 13 => "Domain not validated", - 14 => "Domain has not associated nsset", - 15 => "Domain is not generated into zone", - 16 => "Has relation to other records in registry", - 17 => "Object is going to be deleted", - 18 => "Registrant change prohibited", - 19 => "Domain will be deleted in 11 days", - 20 => "Domain is out of zone after 30 days from expiration", - 21 => "Domain is forced to delete", - 5 => "Domain is administratively kept out of zone", - 6 => "Domain is administratively kept in zone" - } - - map[state_id] - end - end -end diff --git a/app/models/legacy/registrar.rb b/app/models/legacy/registrar.rb deleted file mode 100644 index a0a0c251d..000000000 --- a/app/models/legacy/registrar.rb +++ /dev/null @@ -1,12 +0,0 @@ -module Legacy - class Registrar < Db - self.table_name = :registrar - - has_many :invoices, foreign_key: :registrarid - has_many :acl, foreign_key: :registrarid, class_name: "Legacy::RegistrarAcl" - - def account_balance - invoices.sum(:credit) - end - end -end diff --git a/app/models/legacy/registrar_acl.rb b/app/models/legacy/registrar_acl.rb deleted file mode 100644 index 711d8a2d6..000000000 --- a/app/models/legacy/registrar_acl.rb +++ /dev/null @@ -1,5 +0,0 @@ -module Legacy - class RegistrarAcl < Db - self.table_name = :registraracl - end -end diff --git a/app/models/legacy/zone_ns.rb b/app/models/legacy/zone_ns.rb deleted file mode 100644 index f430e1b11..000000000 --- a/app/models/legacy/zone_ns.rb +++ /dev/null @@ -1,5 +0,0 @@ -module Legacy - class ZoneNs < Db - self.table_name = :zone_ns - end -end diff --git a/app/models/legal_document.rb b/app/models/legal_document.rb index 630c52d98..446087124 100644 --- a/app/models/legal_document.rb +++ b/app/models/legal_document.rb @@ -1,4 +1,4 @@ -class LegalDocument < ActiveRecord::Base +class LegalDocument < ApplicationRecord cattr_accessor :explicitly_write_file include EppErrors MIN_BODY_SIZE = (1.37 * 3.kilobytes).ceil @@ -14,8 +14,7 @@ class LegalDocument < ActiveRecord::Base belongs_to :documentable, polymorphic: true - - validate :val_body_length, if: ->(file){ file.path.blank? && !Rails.env.staging?} + validate :val_body_length, if: ->(file) { file.path.blank? } before_create :add_creator before_save :save_to_filesystem, if: :body @@ -32,7 +31,6 @@ class LegalDocument < ActiveRecord::Base errors.add(:body, :length) if body.nil? || body.size < MIN_BODY_SIZE end - def save_to_filesystem binary = Base64.decode64(body) digest = Digest::SHA1.new.update(binary).to_s @@ -58,7 +56,7 @@ class LegalDocument < ActiveRecord::Base end def add_creator - self.creator_str = ::PaperTrail.whodunnit + self.creator_str = ::PaperTrail.request.whodunnit true end diff --git a/app/models/nameserver.rb b/app/models/nameserver.rb index d9fdde406..3e4051165 100644 --- a/app/models/nameserver.rb +++ b/app/models/nameserver.rb @@ -1,4 +1,4 @@ -class Nameserver < ActiveRecord::Base +class Nameserver < ApplicationRecord include Versions # version/nameserver_version.rb include EppErrors @@ -34,6 +34,8 @@ class Nameserver < ActiveRecord::Base delegate :name, to: :domain, prefix: true + self.ignored_columns = %w[legacy_domain_id] + def epp_code_map { '2302' => [ @@ -46,7 +48,7 @@ class Nameserver < ActiveRecord::Base [:ipv6, :invalid, { value: { obj: 'hostAddr', val: ipv6 } }] ], '2003' => [ - [:ipv4, :blank] + %i[base ip_required], ] } end @@ -81,11 +83,12 @@ class Nameserver < ActiveRecord::Base def glue_record_required? return unless hostname? && domain - hostname.end_with?(domain.name) + + DomainName(hostname).domain == domain.name end def normalize_attributes - self.hostname = hostname.try(:strip).try(:downcase) + self.hostname = hostname.try(:strip).try(:downcase).gsub(/\.$/, '') self.ipv4 = Array(ipv4).reject(&:blank?).map(&:strip) self.ipv6 = Array(ipv6).reject(&:blank?).map(&:strip).map(&:upcase) end diff --git a/app/models/notification.rb b/app/models/notification.rb index d6427323b..e83b2c9da 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -1,4 +1,4 @@ -class Notification < ActiveRecord::Base +class Notification < ApplicationRecord include Versions # version/notification_version.rb belongs_to :registrar diff --git a/app/models/payment_order.rb b/app/models/payment_order.rb new file mode 100644 index 000000000..4317abb38 --- /dev/null +++ b/app/models/payment_order.rb @@ -0,0 +1,102 @@ +class PaymentOrder < ApplicationRecord + include Versions + include ActionView::Helpers::NumberHelper + + PAYMENT_INTERMEDIARIES = ENV['payments_intermediaries'].to_s.strip.split(', ').freeze + PAYMENT_BANKLINK_BANKS = ENV['payments_banks'].to_s.strip.split(', ').freeze + INTERNAL_PAYMENT_METHODS = %w[admin_payment system_payment].freeze + PAYMENT_METHODS = [PAYMENT_INTERMEDIARIES, PAYMENT_BANKLINK_BANKS, + INTERNAL_PAYMENT_METHODS].flatten.freeze + CUSTOMER_PAYMENT_METHODS = [PAYMENT_INTERMEDIARIES, PAYMENT_BANKLINK_BANKS].flatten.freeze + + belongs_to :invoice, optional: false + + validate :invoice_cannot_be_already_paid, on: :create + validate :supported_payment_method + + enum status: { issued: 'issued', paid: 'paid', cancelled: 'cancelled', + failed: 'failed' } + + attr_accessor :return_url, :response_url + + def self.supported_methods + supported = [] + + PAYMENT_METHODS.each do |method| + class_name = ('PaymentOrders::' + method.camelize).constantize + raise(NoMethodError, class_name) unless class_name < PaymentOrder + + supported << class_name + end + + supported + end + + def self.new_with_type(type:, invoice:) + channel = ('PaymentOrders::' + type.camelize).constantize + + PaymentOrder.new(type: channel, invoice: invoice) + end + + # Name of configuration namespace + def self.config_namespace_name; end + + def supported_payment_method + return if PaymentOrder.supported_method?(type) + + errors.add(:type, 'is not supported') + end + + def invoice_cannot_be_already_paid + return unless invoice&.paid? + + errors.add(:invoice, 'is already paid') + end + + def self.supported_method?(name, shortname: false) + some_class = if shortname + ('PaymentOrders::' + name.camelize).constantize + else + name.constantize + end + supported_methods.include? some_class + rescue NameError + false + end + + def base_transaction(sum:, paid_at:, buyer_name:) + BankTransaction.new( + description: invoice.order, + reference_no: invoice.reference_no, + currency: invoice.currency, + iban: invoice.seller_iban, + sum: sum, + paid_at: paid_at, + buyer_name: buyer_name + ) + end + + def complete_transaction + return NoMethodError unless payment_received? + + paid! + transaction = composed_transaction + transaction.save! && transaction.bind_invoice(invoice.number) + return unless transaction.errors.any? + + worded_errors = 'Failed to bind. ' + transaction.errors.full_messages.each do |err| + worded_errors << "#{err}, " + end + + update!(notes: worded_errors) + end + + def channel + type.gsub('PaymentOrders::', '') + end + + def form_url + ENV["payments_#{self.class.config_namespace_name}_url"] + end +end diff --git a/app/models/payment_orders.rb b/app/models/payment_orders.rb deleted file mode 100644 index 921af0cd4..000000000 --- a/app/models/payment_orders.rb +++ /dev/null @@ -1,15 +0,0 @@ -module PaymentOrders - PAYMENT_INTERMEDIARIES = ENV['payments_intermediaries'].to_s.strip.split(', ').freeze - PAYMENT_BANKLINK_BANKS = ENV['payments_banks'].to_s.strip.split(', ').freeze - PAYMENT_METHODS = [PAYMENT_INTERMEDIARIES, PAYMENT_BANKLINK_BANKS].flatten.freeze - - def self.create_with_type(type, invoice, opts = {}) - raise ArgumentError unless PAYMENT_METHODS.include?(type) - - if PAYMENT_BANKLINK_BANKS.include?(type) - BankLink.new(type, invoice, opts) - elsif type == 'every_pay' - EveryPay.new(type, invoice, opts) - end - end -end diff --git a/app/models/payment_orders/admin_payment.rb b/app/models/payment_orders/admin_payment.rb new file mode 100644 index 000000000..05ae061fb --- /dev/null +++ b/app/models/payment_orders/admin_payment.rb @@ -0,0 +1,9 @@ +module PaymentOrders + class AdminPayment < PaymentOrder + CONFIG_NAMESPACE = 'admin_payment'.freeze + + def self.config_namespace_name + CONFIG_NAMESPACE + end + end +end diff --git a/app/models/payment_orders/bank_link.rb b/app/models/payment_orders/bank_link.rb index e568da0df..c8714d245 100644 --- a/app/models/payment_orders/bank_link.rb +++ b/app/models/payment_orders/bank_link.rb @@ -1,44 +1,44 @@ module PaymentOrders - class BankLink < Base - BANK_LINK_VERSION = '008' + class BankLink < PaymentOrder + BANK_LINK_VERSION = '008'.freeze - NEW_TRANSACTION_SERVICE_NUMBER = '1012' - SUCCESSFUL_PAYMENT_SERVICE_NUMBER = '1111' - CANCELLED_PAYMENT_SERVICE_NUMBER = '1911' + NEW_TRANSACTION_SERVICE_NUMBER = '1012'.freeze + SUCCESSFUL_PAYMENT_SERVICE_NUMBER = '1111'.freeze + CANCELLED_PAYMENT_SERVICE_NUMBER = '1911'.freeze - NEW_MESSAGE_KEYS = %w(VK_SERVICE VK_VERSION VK_SND_ID VK_STAMP VK_AMOUNT + NEW_MESSAGE_KEYS = %w[VK_SERVICE VK_VERSION VK_SND_ID VK_STAMP VK_AMOUNT VK_CURR VK_REF VK_MSG VK_RETURN VK_CANCEL - VK_DATETIME).freeze - SUCCESS_MESSAGE_KEYS = %w(VK_SERVICE VK_VERSION VK_SND_ID VK_REC_ID VK_STAMP + VK_DATETIME].freeze + SUCCESS_MESSAGE_KEYS = %w[VK_SERVICE VK_VERSION VK_SND_ID VK_REC_ID VK_STAMP VK_T_NO VK_AMOUNT VK_CURR VK_REC_ACC VK_REC_NAME VK_SND_ACC VK_SND_NAME VK_REF VK_MSG - VK_T_DATETIME).freeze - CANCEL_MESSAGE_KEYS = %w(VK_SERVICE VK_VERSION VK_SND_ID VK_REC_ID VK_STAMP - VK_REF VK_MSG).freeze + VK_T_DATETIME].freeze + CANCEL_MESSAGE_KEYS = %w[VK_SERVICE VK_VERSION VK_SND_ID VK_REC_ID VK_STAMP + VK_REF VK_MSG].freeze def form_fields hash = {} - hash["VK_SERVICE"] = NEW_TRANSACTION_SERVICE_NUMBER - hash["VK_VERSION"] = BANK_LINK_VERSION - hash["VK_SND_ID"] = seller_account - hash["VK_STAMP"] = invoice.number - hash["VK_AMOUNT"] = number_with_precision(invoice.total, precision: 2, separator: ".") - hash["VK_CURR"] = invoice.currency - hash["VK_REF"] = "" - hash["VK_MSG"] = invoice.order - hash["VK_RETURN"] = return_url - hash["VK_CANCEL"] = return_url - hash["VK_DATETIME"] = Time.zone.now.strftime("%Y-%m-%dT%H:%M:%S%z") - hash["VK_MAC"] = calc_mac(hash) - hash["VK_ENCODING"] = "UTF-8" - hash["VK_LANG"] = "ENG" + hash['VK_SERVICE'] = NEW_TRANSACTION_SERVICE_NUMBER + hash['VK_VERSION'] = BANK_LINK_VERSION + hash['VK_SND_ID'] = seller_account + hash['VK_STAMP'] = invoice.number + hash['VK_AMOUNT'] = number_with_precision(invoice.total, precision: 2, separator: ".") + hash['VK_CURR'] = invoice.currency + hash['VK_REF'] = '' + hash['VK_MSG'] = invoice.order + hash['VK_RETURN'] = return_url + hash['VK_CANCEL'] = return_url + hash['VK_DATETIME'] = Time.zone.now.strftime('%Y-%m-%dT%H:%M:%S%z') + hash['VK_MAC'] = calc_mac(hash) + hash['VK_ENCODING'] = 'UTF-8' + hash['VK_LANG'] = 'ENG' hash end def valid_response_from_intermediary? return false unless response - case response["VK_SERVICE"] + case response['VK_SERVICE'] when SUCCESSFUL_PAYMENT_SERVICE_NUMBER valid_successful_transaction? when CANCELLED_PAYMENT_SERVICE_NUMBER @@ -48,28 +48,31 @@ module PaymentOrders end end - def complete_transaction - return unless valid_successful_transaction? + def payment_received? + valid_response_from_intermediary? && settled_payment? + end - transaction = BankTransaction.find_by( - description: invoice.order, - currency: invoice.currency, - iban: invoice.seller_iban - ) + def create_failure_report + notes = "User failed to make payment. Bank responded with code #{response['VK_SERVICE']}" + status = 'cancelled' + update!(notes: notes, status: status) + end - transaction.sum = response['VK_AMOUNT'] - transaction.bank_reference = response['VK_T_NO'] - transaction.buyer_bank_code = response["VK_SND_ID"] - transaction.buyer_iban = response["VK_SND_ACC"] - transaction.buyer_name = response["VK_SND_NAME"] - transaction.paid_at = Time.parse(response["VK_T_DATETIME"]) + def composed_transaction + paid_at = Time.parse(response['VK_T_DATETIME']) + transaction = base_transaction(sum: response['VK_AMOUNT'], + paid_at: paid_at, + buyer_name: response['VK_SND_NAME']) - transaction.save! - transaction.autobind_invoice + transaction.bank_reference = response['VK_T_NO'] + transaction.buyer_bank_code = response['VK_SND_ID'] + transaction.buyer_iban = response['VK_SND_ACC'] + + transaction end def settled_payment? - response["VK_SERVICE"] == SUCCESSFUL_PAYMENT_SERVICE_NUMBER + response['VK_SERVICE'] == SUCCESSFUL_PAYMENT_SERVICE_NUMBER end private @@ -88,17 +91,15 @@ module PaymentOrders def valid_amount? source = number_with_precision( - BigDecimal.new(response["VK_AMOUNT"]), precision: 2, separator: "." - ) - target = number_with_precision( - invoice.total, precision: 2, separator: "." + BigDecimal(response['VK_AMOUNT']), precision: 2, separator: '.' ) + target = number_with_precision(invoice.total, precision: 2, separator: '.') source == target end def valid_currency? - invoice.currency == response["VK_CURR"] + invoice.currency == response['VK_CURR'] end def sign(data) @@ -116,7 +117,7 @@ module PaymentOrders def valid_mac?(hash, keys) data = keys.map { |element| prepend_size(hash[element]) }.join - verify_mac(data, hash["VK_MAC"]) + verify_mac(data, hash['VK_MAC']) end def verify_mac(data, mac) @@ -125,22 +126,22 @@ module PaymentOrders end def prepend_size(value) - value = (value || "").to_s.strip - string = "" + value = (value || '').to_s.strip + string = '' string << format("%03i", value.size) string << value end def seller_account - ENV["payments_#{type}_seller_account"] + ENV["payments_#{self.class.config_namespace_name}_seller_account"] end def seller_certificate - ENV["payments_#{type}_seller_private"] + ENV["payments_#{self.class.config_namespace_name}_seller_private"] end def bank_certificate - ENV["payments_#{type}_bank_certificate"] + ENV["payments_#{self.class.config_namespace_name}_bank_certificate"] end end end diff --git a/app/models/payment_orders/base.rb b/app/models/payment_orders/base.rb deleted file mode 100644 index cf0293025..000000000 --- a/app/models/payment_orders/base.rb +++ /dev/null @@ -1,33 +0,0 @@ -module PaymentOrders - class Base - include ActionView::Helpers::NumberHelper - - attr_reader :type, - :invoice, - :return_url, - :response_url, - :response - - def initialize(type, invoice, opts = {}) - @type = type - @invoice = invoice - @return_url = opts[:return_url] - @response_url = opts[:response_url] - @response = opts[:response] - end - - def create_transaction - transaction = BankTransaction.where(description: invoice.order).first_or_initialize( - reference_no: invoice.reference_no, - currency: invoice.currency, - iban: invoice.seller_iban - ) - - transaction.save! - end - - def form_url - ENV["payments_#{type}_url"] - end - end -end diff --git a/app/models/payment_orders/every_pay.rb b/app/models/payment_orders/every_pay.rb index b4ddcdf29..2695c20e0 100644 --- a/app/models/payment_orders/every_pay.rb +++ b/app/models/payment_orders/every_pay.rb @@ -1,9 +1,15 @@ module PaymentOrders - class EveryPay < Base - USER = ENV['payments_every_pay_api_user'].freeze - KEY = ENV['payments_every_pay_api_key'].freeze - ACCOUNT_ID = ENV['payments_every_pay_seller_account'].freeze - SUCCESSFUL_PAYMENT = %w(settled authorized).freeze + class EveryPay < PaymentOrder + USER = ENV['payments_every_pay_api_user'] + KEY = ENV['payments_every_pay_api_key'] + ACCOUNT_ID = ENV['payments_every_pay_seller_account'] + SUCCESSFUL_PAYMENT = %w[settled authorized].freeze + + CONFIG_NAMESPACE = 'every_pay'.freeze + + def self.config_namespace_name + CONFIG_NAMESPACE + end def form_fields base_json = base_params @@ -20,28 +26,28 @@ module PaymentOrders def valid_response_from_intermediary? return false unless response + valid_hmac? && valid_amount? && valid_account? end def settled_payment? - SUCCESSFUL_PAYMENT.include?(response[:payment_state]) + SUCCESSFUL_PAYMENT.include?(response['payment_state']) end - def complete_transaction - return unless valid_response_from_intermediary? && settled_payment? + def payment_received? + valid_response_from_intermediary? && settled_payment? + end - transaction = BankTransaction.find_by( - description: invoice.order, - currency: invoice.currency, - iban: invoice.seller_iban - ) + def composed_transaction + base_transaction(sum: response['amount'], + paid_at: Date.strptime(response['timestamp'], '%s'), + buyer_name: response['cc_holder_name']) + end - transaction.sum = response[:amount] - transaction.paid_at = Date.strptime(response[:timestamp], '%s') - transaction.buyer_name = response[:cc_holder_name] - - transaction.save! - transaction.autobind_invoice + def create_failure_report + notes = "User failed to make valid payment. Payment state: #{response['payment_state']}" + status = 'cancelled' + update!(notes: notes, status: status) end private @@ -61,24 +67,27 @@ module PaymentOrders end def valid_hmac? - hmac_fields = response[:hmac_fields].split(',') + hmac_fields = response['hmac_fields'].split(',') hmac_hash = {} hmac_fields.map do |field| - symbol = field.to_sym - hmac_hash[symbol] = response[symbol] + hmac_hash[field] = response[field] end hmac_string = hmac_hash.map { |key, _v| "#{key}=#{hmac_hash[key]}" }.join('&') expected_hmac = OpenSSL::HMAC.hexdigest('sha1', KEY, hmac_string) - expected_hmac == response[:hmac] + expected_hmac == response['hmac'] + rescue NoMethodError + false end def valid_amount? - invoice.total == BigDecimal.new(response[:amount]) + return false unless response.key? 'amount' + + invoice.total == BigDecimal(response['amount']) end def valid_account? - response[:account_id] == ACCOUNT_ID + response['account_id'] == ACCOUNT_ID end end end diff --git a/app/models/payment_orders/lhv.rb b/app/models/payment_orders/lhv.rb new file mode 100644 index 000000000..4c9f59c4a --- /dev/null +++ b/app/models/payment_orders/lhv.rb @@ -0,0 +1,7 @@ +module PaymentOrders + class Lhv < BankLink + def self.config_namespace_name + 'lhv' + end + end +end diff --git a/app/models/payment_orders/seb.rb b/app/models/payment_orders/seb.rb new file mode 100644 index 000000000..878d877a7 --- /dev/null +++ b/app/models/payment_orders/seb.rb @@ -0,0 +1,7 @@ +module PaymentOrders + class Seb < BankLink + def self.config_namespace_name + 'seb' + end + end +end diff --git a/app/models/payment_orders/swed.rb b/app/models/payment_orders/swed.rb new file mode 100644 index 000000000..ff3aca3d1 --- /dev/null +++ b/app/models/payment_orders/swed.rb @@ -0,0 +1,7 @@ +module PaymentOrders + class Swed < BankLink + def self.config_namespace_name + 'swed' + end + end +end diff --git a/app/models/payment_orders/system_payment.rb b/app/models/payment_orders/system_payment.rb new file mode 100644 index 000000000..47c75ebe3 --- /dev/null +++ b/app/models/payment_orders/system_payment.rb @@ -0,0 +1,9 @@ +module PaymentOrders + class SystemPayment < PaymentOrder + CONFIG_NAMESPACE = 'system_payment'.freeze + + def self.config_namespace_name + CONFIG_NAMESPACE + end + end +end diff --git a/app/models/que_job.rb b/app/models/que_job.rb index 5eed581fc..f9dd50ac8 100644 --- a/app/models/que_job.rb +++ b/app/models/que_job.rb @@ -1,4 +1,4 @@ # To be able to remove existing jobs -class QueJob < ActiveRecord::Base +class QueJob < ApplicationRecord self.primary_key = 'job_id' end diff --git a/app/models/registrant_user.rb b/app/models/registrant_user.rb index 1e787b8b3..e7ce9cc3b 100644 --- a/app/models/registrant_user.rb +++ b/app/models/registrant_user.rb @@ -98,4 +98,4 @@ class RegistrantUser < User user end end -end \ No newline at end of file +end diff --git a/app/models/registrant_verification.rb b/app/models/registrant_verification.rb index 95e24d36b..097f0cfa9 100644 --- a/app/models/registrant_verification.rb +++ b/app/models/registrant_verification.rb @@ -1,17 +1,19 @@ # Used in Registrant portal to collect registrant verifications # Registrant postgres user can access this table directly. -class RegistrantVerification < ActiveRecord::Base +class RegistrantVerification < ApplicationRecord + include Versions # version/domain_version.rb + # actions CONFIRMED = 'confirmed' REJECTED = 'rejected' - + # action types DOMAIN_REGISTRANT_CHANGE = 'domain_registrant_change' DOMAIN_DELETE = 'domain_delete' belongs_to :domain - validates :verification_token, :domain_name, :domain, :action, :action_type, presence: true + validates :verification_token, :domain, :action, :action_type, presence: true def domain_registrant_change_confirm!(initiator) self.action_type = DOMAIN_REGISTRANT_CHANGE diff --git a/app/models/registrar.rb b/app/models/registrar.rb index 8a65c0b06..470d768b7 100644 --- a/app/models/registrar.rb +++ b/app/models/registrar.rb @@ -1,5 +1,8 @@ -class Registrar < ActiveRecord::Base +class Registrar < ApplicationRecord include Versions # version/registrar_version.rb + include Concerns::Registrar::BookKeeping + include Concerns::EmailVerifable + include Concerns::Registrar::LegalDoc has_many :domains, dependent: :restrict_with_error has_many :contacts, dependent: :restrict_with_error @@ -21,20 +24,19 @@ class Registrar < ActiveRecord::Base validates :reference_no, format: Billing::ReferenceNo::REGEXP validate :forbid_special_code - validates :vat_rate, presence: true, if: 'vat_liable_in_foreign_country? && vat_no.blank?' + validates :vat_rate, presence: true, if: -> { vat_liable_in_foreign_country? && vat_no.blank? } validates :vat_rate, absence: true, if: :vat_liable_locally? - validates :vat_rate, absence: true, if: 'vat_liable_in_foreign_country? && vat_no?' + validates :vat_rate, absence: true, if: -> { vat_liable_in_foreign_country? && vat_no? } validates :vat_rate, numericality: { greater_than_or_equal_to: 0, less_than: 100 }, allow_nil: true - validate :forbid_special_code - attribute :vat_rate, ::Type::VATRate.new after_initialize :set_defaults - validates :email, :billing_email, - email_format: { message: :invalid }, - allow_blank: true, if: proc { |c| c.email_changed? } + validate :correct_email_format, if: proc { |c| c.will_save_change_to_email? } + validate :correct_billing_email_format + + alias_attribute :contact_email, :email WHOIS_TRIGGERS = %w(name email phone street city state zip) @@ -44,6 +46,8 @@ class Registrar < ActiveRecord::Base RegenerateRegistrarWhoisesJob.enqueue id end + self.ignored_columns = %w[legacy_id] + class << self def ordered order(name: :asc) @@ -95,9 +99,7 @@ class Registrar < ActiveRecord::Base } ] ) - - e_invoice = invoice.to_e_invoice - e_invoice.deliver + SendEInvoiceJob.enqueue(invoice.id) invoice end @@ -174,6 +176,11 @@ class Registrar < ActiveRecord::Base iban end + def billing_email + return contact_email if self[:billing_email].blank? + self[:billing_email] + end + private def set_defaults @@ -187,4 +194,4 @@ class Registrar < ActiveRecord::Base def vat_liable_in_foreign_country? !vat_liable_locally? end -end \ No newline at end of file +end diff --git a/app/models/reserved_domain.rb b/app/models/reserved_domain.rb index 2e3d17a20..4c9df3269 100644 --- a/app/models/reserved_domain.rb +++ b/app/models/reserved_domain.rb @@ -1,13 +1,17 @@ -class ReservedDomain < ActiveRecord::Base +class ReservedDomain < ApplicationRecord include Versions # version/reserved_domain_version.rb + include WhoisStatusPopulate before_save :fill_empty_passwords before_save :generate_data + before_save :sync_dispute_password after_destroy :remove_data validates :name, domain_name: true, uniqueness: true alias_attribute :registration_code, :password + self.ignored_columns = %w[legacy_id] + class << self def pw_for(domain_name) name_in_ascii = SimpleIDN.to_ascii(domain_name) @@ -39,23 +43,21 @@ class ReservedDomain < ActiveRecord::Base self.password = SecureRandom.hex end + def sync_dispute_password + dispute = Dispute.active.find_by(domain_name: name) + self.password = dispute.password if dispute.present? + end + def generate_data return if Domain.where(name: name).any? wr = Whois::Record.find_or_initialize_by(name: name) - wr.json = @json = generate_json # we need @json to bind to class + wr.json = @json = generate_json(wr, domain_status: 'Reserved') # we need @json to bind to class wr.save end alias_method :update_whois_record, :generate_data - def generate_json - h = HashWithIndifferentAccess.new - h[:name] = self.name - h[:status] = ['Reserved'] - h - end - def remove_data UpdateWhoisRecordJob.enqueue name, 'reserved' end diff --git a/app/models/retained_domains.rb b/app/models/retained_domains.rb new file mode 100644 index 000000000..d9ab42b3b --- /dev/null +++ b/app/models/retained_domains.rb @@ -0,0 +1,91 @@ +# Hiding the queries behind its own class will allow us to include disputed or +# auctioned domains without meddling up with controller logic. +class RetainedDomains + RESERVED = 'reserved'.freeze + BLOCKED = 'blocked'.freeze + DISPUTED = 'disputed'.freeze + + attr_reader :domains, + :type + + def initialize(params) + @type = establish_type(params) + @domains = gather_domains + end + + delegate :count, to: :domains + + def to_jsonable + domains.map { |el| domain_to_jsonable(el) } + end + + private + + def establish_type(params) + type = params[:type] + + case type + when RESERVED then :reserved + when BLOCKED then :blocked + when DISPUTED then :disputed + else :all + end + end + + def gather_domains + blocked_domains.to_a + .union(reserved_domains.to_a) + .union(disputed_domains.to_a) + end + + def blocked_domains + if %i[all blocked].include?(type) + BlockedDomain.order(name: :desc).all + else + [] + end + end + + def reserved_domains + if %i[all reserved].include?(type) + ReservedDomain.order(name: :desc).all + else + [] + end + end + + def disputed_domains + if %i[all disputed].include?(type) + Dispute.order(domain_name: :desc).active + else + [] + end + end + + def domain_to_jsonable(domain) + status = get_status(domain) + domain_name = get_domain_name(domain) + punycode = SimpleIDN.to_ascii(domain_name) + + { + name: domain_name, + status: status, + punycode_name: punycode, + } + end + + def get_status(domain) + case domain + when ReservedDomain then RESERVED + when BlockedDomain then BLOCKED + when Dispute then DISPUTED + end + end + + def get_domain_name(domain) + case domain + when Dispute then domain.domain_name + else domain.name + end + end +end diff --git a/app/models/setting.rb b/app/models/setting.rb index 64a20c34f..b39767089 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -1,72 +1,5 @@ -class Setting < RailsSettings::Base - include Versions # version/setting_version.rb - source Rails.root.join('config', 'app.yml') +# frozen_string_literal: true - # When config/app.yml has changed, you need change this prefix to v2, v3 ... to expires caches - # cache_prefix { "v1" } - - def self.reload_settings! - STDOUT << "#{Time.zone.now.utc} - Clearing settings cache\n" - Rails.cache.delete_matched('settings:.*') - STDOUT << "#{Time.zone.now.utc} - Settings cache cleared\n" - end - - - # cannot do instance validation because CachedSetting use save! - def self.params_errors(params) - errors = {} - # DS data allowed and Allow key data cannot be both true - if !!params["key_data_allowed"] && params["key_data_allowed"] == params["ds_data_allowed"] - msg = "#{I18n.t(:key_data_allowed)} and #{I18n.t(:ds_data_with_key_allowed)} cannot be both true" - errors["key_data_allowed"] = msg - errors["ds_data_allowed"] = msg - end - - return errors - end - - def self.integer_settings - %i[ - admin_contacts_min_count - admin_contacts_max_count - tech_contacts_min_count - tech_contacts_max_count - orphans_contacts_in_months - ds_digest_type - dnskeys_min_count - dnskeys_max_count - ns_min_count - ns_max_count - transfer_wait_time - invoice_number_min - invoice_number_max - days_to_keep_invoices_active - days_to_keep_overdue_invoices_active - days_to_renew_domain_before_expire - expire_warning_period - redemption_grace_period - expire_pending_confirmation - ] - end - - def self.float_settings - %i[ - registry_vat_prc - minimum_deposit - ] - end - - def self.boolean_settings - %i[ - ds_data_allowed - key_data_allowed - client_side_status_editing_enabled - registrar_ip_whitelist_enabled - api_ip_whitelist_enabled - request_confrimation_on_registrant_change_enabled - request_confirmation_on_domain_deletion_enabled - nameserver_required - address_processing - ] - end +class Setting < SettingEntry + # Bridge Setting calls to SettingEntry, so we don't have to drop legacy settings yet end diff --git a/app/models/setting_entry.rb b/app/models/setting_entry.rb new file mode 100644 index 000000000..966831881 --- /dev/null +++ b/app/models/setting_entry.rb @@ -0,0 +1,92 @@ +class SettingEntry < ApplicationRecord + include Versions + validates :code, presence: true, uniqueness: true, format: { with: /\A([a-z])[a-z|_]+[a-z]\z/ } + validates :format, presence: true + validates :group, presence: true + validate :validate_value_format + validate :validate_code_is_not_using_reserved_name + before_update :replace_boolean_nil_with_false + + VALUE_FORMATS = { + string: :string_format, + integer: :integer_format, + float: :float_format, + boolean: :boolean_format, + hash: :hash_format, + array: :array_format, + }.with_indifferent_access.freeze + + def retrieve + method = VALUE_FORMATS[format] + return false if self.format == 'boolean' && value.blank? + return if value.blank? + + send(method) + end + + def self.with_group(group_name) + SettingEntry.order(id: :asc).where(group: group_name) + end + + # rubocop:disable Style/MethodMissingSuper + # rubocop:disable Style/MissingRespondToMissing + def self.method_missing(method, *args) + super(method, *args) + rescue NoMethodError + get_or_set(method.to_s, args[0]) + end + # rubocop:enable Style/MissingRespondToMissing + # rubocop:enable Style/MethodMissingSuper + + def self.get_or_set(method_name, arg) + if method_name[-1] == '=' + SettingEntry.find_by!(code: method_name.sub('=', '')).update(value: arg.to_s) + else + stg = SettingEntry.find_by(code: method_name) + stg ? stg.retrieve : nil + end + end + + # Hooks + def replace_boolean_nil_with_false + return unless self.format == 'boolean' + return if value == 'true' + + self.value = 'false' + end + + def validate_code_is_not_using_reserved_name + disallowed = [] + ActiveRecord::Base.instance_methods.sort.each { |m| disallowed << m.to_s } + errors.add(:code, :invalid) if disallowed.include? code + end + + def validate_value_format + formats = VALUE_FORMATS.with_indifferent_access + errors.add(:format, :invalid) unless formats.keys.any? format + end + + def string_format + value + end + + def integer_format + value.to_i + end + + def float_format + value.to_f + end + + def boolean_format + value == 'true' + end + + def hash_format + JSON.parse(value) + end + + def array_format + JSON.parse(value).to_a + end +end diff --git a/app/models/type/vat_rate.rb b/app/models/type/vat_rate.rb index 5ee993211..6a31e389b 100644 --- a/app/models/type/vat_rate.rb +++ b/app/models/type/vat_rate.rb @@ -1,10 +1,10 @@ module Type class VATRate < ActiveRecord::Type::Decimal - def type_cast_from_database(value) + def deserialize(value) super * 100 if value end - def type_cast_for_database(value) + def serialize(value) super / 100.0 if value end end diff --git a/app/models/user.rb b/app/models/user.rb index 573cddc94..6b16bd508 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,10 +1,12 @@ -class User < ActiveRecord::Base +class User < ApplicationRecord include Versions # version/user_version.rb has_many :actions, dependent: :restrict_with_exception attr_accessor :phone + self.ignored_columns = %w[legacy_id] + def id_role_username "#{self.id}-#{self.class}: #{self.username}" end diff --git a/app/models/version/keyrelay_version.rb b/app/models/version/keyrelay_version.rb deleted file mode 100644 index fececa6e8..000000000 --- a/app/models/version/keyrelay_version.rb +++ /dev/null @@ -1,5 +0,0 @@ -class KeyrelayVersion < PaperTrail::Version - include VersionSession - self.table_name = :log_keyrelays - self.sequence_name = :log_keyrelays_id_seq -end diff --git a/app/models/version/payment_order_version.rb b/app/models/version/payment_order_version.rb new file mode 100644 index 000000000..e556f1021 --- /dev/null +++ b/app/models/version/payment_order_version.rb @@ -0,0 +1,4 @@ +class PaymentOrderVersion < PaperTrail::Version + self.table_name = :log_payment_orders + self.sequence_name = :log_payment_orders_id_seq +end diff --git a/app/models/version/registrant_verification_version.rb b/app/models/version/registrant_verification_version.rb new file mode 100644 index 000000000..b7dbb8852 --- /dev/null +++ b/app/models/version/registrant_verification_version.rb @@ -0,0 +1,7 @@ +class RegistrantVerificationVersion < PaperTrail::Version + include VersionSession + self.table_name = :log_registrant_verifications + self.sequence_name = :log_registrant_verifications_id_seq + + scope :deleted, -> { where(event: 'destroy') } +end diff --git a/app/models/version/setting_entry_version.rb b/app/models/version/setting_entry_version.rb new file mode 100644 index 000000000..de1e4d1ca --- /dev/null +++ b/app/models/version/setting_entry_version.rb @@ -0,0 +1,4 @@ +class SettingEntryVersion < PaperTrail::Version + self.table_name = :log_setting_entries + self.sequence_name = :log_setting_entries +end diff --git a/app/models/white_ip.rb b/app/models/white_ip.rb index 251fc60ac..303ff5886 100644 --- a/app/models/white_ip.rb +++ b/app/models/white_ip.rb @@ -1,4 +1,4 @@ -class WhiteIp < ActiveRecord::Base +class WhiteIp < ApplicationRecord include Versions belongs_to :registrar diff --git a/app/models/whois/record.rb b/app/models/whois/record.rb index ae7422403..1d827e22a 100644 --- a/app/models/whois/record.rb +++ b/app/models/whois/record.rb @@ -16,7 +16,8 @@ module Whois elsif auction.awaiting_payment? || auction.payment_received? update!(json: { name: auction.domain, status: ['PendingRegistration'], - disclaimer: self.class.disclaimer }) + disclaimer: self.class.disclaimer, + registration_deadline: auction.whois_deadline }) end end end diff --git a/app/models/whois/server.rb b/app/models/whois/server.rb index 2cec52e4e..bec234b6b 100644 --- a/app/models/whois/server.rb +++ b/app/models/whois/server.rb @@ -1,5 +1,5 @@ module Whois - class Server < ActiveRecord::Base + class Server < ApplicationRecord self.abstract_class = true establish_connection :"whois_#{Rails.env}" end diff --git a/app/models/whois_record.rb b/app/models/whois_record.rb index 8d91c85ee..4994283c9 100644 --- a/app/models/whois_record.rb +++ b/app/models/whois_record.rb @@ -1,5 +1,5 @@ require "erb" -class WhoisRecord < ActiveRecord::Base +class WhoisRecord < ApplicationRecord belongs_to :domain belongs_to :registrar @@ -84,6 +84,7 @@ class WhoisRecord < ActiveRecord::Base def populate return if domain_id.blank? + self.json = generated_json self.name = json['name'] self.registrar_id = domain.registrar_id if domain # for faster registrar updates diff --git a/app/validators/domain_name_validator.rb b/app/validators/domain_name_validator.rb index 0d5638b37..3372bb952 100644 --- a/app/validators/domain_name_validator.rb +++ b/app/validators/domain_name_validator.rb @@ -1,4 +1,6 @@ class DomainNameValidator < ActiveModel::EachValidator + # rubocop:disable Metrics/CyclomaticComplexity + # rubocop:disable Metrics/LineLength def validate_each(record, attribute, value) if !self.class.validate_format(value) record.errors[attribute] << (options[:message] || record.errors.generate_message(attribute, :invalid)) @@ -27,14 +29,19 @@ class DomainNameValidator < ActiveModel::EachValidator end unicode_chars = /\u00E4\u00F5\u00F6\u00FC\u0161\u017E/ # äõöüšž - regexp = /\A[a-zA-Z0-9#{unicode_chars.source}][a-zA-Z0-9#{unicode_chars.source}-]{0,61}[a-zA-Z0-9#{unicode_chars.source}]\.#{general_domains.source}\z/ - !!(value =~ regexp) + regexp = /\A[a-zA-Z0-9#{unicode_chars.source}][a-zA-Z0-9#{unicode_chars.source}-]{0,62}\.#{general_domains.source}\z/ + end_regexp = /\-\.#{general_domains.source}\z/ # should not contain dash as a closing char + !!(value =~ regexp && value !~ end_regexp) end def validate_blocked(value) return true unless value - return false if BlockedDomain.where(name: value).count.positive? + return false if BlockedDomain.where(name: value).any? + return false if BlockedDomain.where(name: SimpleIDN.to_unicode(value)).any? + DNS::Zone.where(origin: value).count.zero? end end + # rubocop:enable Metrics/CyclomaticComplexity + # rubocop:enable Metrics/LineLength end diff --git a/app/views/admin/account_activities/_search_form.html.erb b/app/views/admin/account_activities/_search_form.html.erb new file mode 100644 index 000000000..bf353a936 --- /dev/null +++ b/app/views/admin/account_activities/_search_form.html.erb @@ -0,0 +1,65 @@ +
+
+ <%= search_form_for @q, url: [:admin, :account_activities], html: { style: 'margin-bottom: 0;' } do |f| %> +
+
+
+ <%= f.label t(:registrar_name) %> + <%= f.select :account_registrar_id_in, Registrar.all.map { |x| [x, x.id] }, {}, class: 'form-control js-combobox', placeholder: t(:choose), multiple: true %> +
+
+
+ +
+
+
+ <%= f.label t(:activity_type) %> + <%= f.select :activity_type_in, AccountActivity.types_for_select, {}, class: 'form-control js-combobox', placeholder: t(:choose), multiple: true %> +
+
+ +
+
+ <%= f.label t(:description) %> + <%= f.search_field :description_cont, class: 'form-control', placeholder: t(:description), autocomplete: 'off' %> +
+
+
+ +
+
+
+ <%= f.label t(:receipt_date_from) %> + <%= f.search_field :created_at_gteq, value: params[:q][:created_at_gteq], class: 'form-control js-datepicker', placeholder: t(:receipt_date_from) %> +
+
+ +
+
+ <%= f.label t(:receipt_date_until) %> + <%= f.search_field :created_at_lteq, value: params[:q][:created_at_lteq], class: 'form-control js-datepicker', placeholder: t(:receipt_date_until) %> +
+
+ +
+
+ <%= label_tag t(:results_per_page) %> + <%= text_field_tag :results_per_page, params[:results_per_page], class: 'form-control', placeholder: t(:results_per_page) %> +
+
+ +
+ + <%= button_tag t('.download_btn'), + formaction: admin_account_activities_path(format: 'csv'), + class: 'btn btn-default' %> + <%= link_to(t('.reset_btn'), admin_account_activities_path, class: 'btn btn-default') %> +
+
+ <% end %> +
+
diff --git a/app/views/admin/account_activities/index.haml b/app/views/admin/account_activities/index.haml index 1f201f255..2e1d57dc6 100644 --- a/app/views/admin/account_activities/index.haml +++ b/app/views/admin/account_activities/index.haml @@ -1,44 +1,6 @@ -- content_for :actions do - = link_to(t(:export_csv), url_for(params.merge(format: 'csv')), class: 'btn btn-default') - = render 'shared/title', name: t(:account_activities) += render 'search_form' -.row - .col-md-12 - = search_form_for @q, url: [:admin, :account_activities], html: { style: 'margin-bottom: 0;' } do |f| - .row - .col-md-12 - .form-group - = f.label t(:registrar_name) - = f.select :account_registrar_id_in, Registrar.all.map { |x| [x, x.id] }, {}, class: 'form-control js-combobox', placeholder: t(:choose), multiple: true - .row - .col-md-6 - .form-group - = f.label t(:activity_type) - = f.select :activity_type_in, AccountActivity.types_for_select, {}, class: 'form-control js-combobox', placeholder: t(:choose), multiple: true - .col-md-6 - .form-group - = f.label t(:description) - = f.search_field :description_cont, class: 'form-control', placeholder: t(:description), autocomplete: 'off' - .row - .col-md-3 - .form-group - = f.label t(:receipt_date_from) - = f.search_field :created_at_gteq, value: params[:q][:created_at_gteq], class: 'form-control js-datepicker', placeholder: t(:receipt_date_from) - .col-md-3 - .form-group - = f.label t(:receipt_date_until) - = f.search_field :created_at_lteq, value: params[:q][:created_at_lteq], class: 'form-control js-datepicker', placeholder: t(:receipt_date_until) - .col-md-3 - .form-group - = label_tag t(:results_per_page) - = text_field_tag :results_per_page, params[:results_per_page], class: 'form-control', placeholder: t(:results_per_page) - .col-md-3{style: 'padding-top: 25px;'} - %button.btn.btn-default.search -   - %span.glyphicon.glyphicon-search -   - = link_to(t('.reset_btn'), admin_account_activities_path, class: 'btn btn-default') .row .col-md-3 .col-md-3 diff --git a/app/views/admin/api_users/_api_user.html.erb b/app/views/admin/api_users/_api_user.html.erb new file mode 100644 index 000000000..d8412a519 --- /dev/null +++ b/app/views/admin/api_users/_api_user.html.erb @@ -0,0 +1,5 @@ + + <%= link_to api_user, admin_registrar_api_user_path(api_user.registrar, api_user) %> + <%= link_to api_user.registrar, admin_registrar_path(api_user.registrar) %> + <%= api_user.active %> + diff --git a/app/views/admin/api_users/_form.haml b/app/views/admin/api_users/_form.haml deleted file mode 100644 index 12ea322aa..000000000 --- a/app/views/admin/api_users/_form.haml +++ /dev/null @@ -1,57 +0,0 @@ -= form_for([:admin, @api_user], multipart: true, - html: {class: 'form-horizontal', autocomplete: 'off'}) do |f| - = render 'shared/full_errors', object: @api_user - - .row - .col-md-8 - .form-group - .col-md-4.control-label - = f.label :username, nil, class: 'required' - .col-md-7 - = f.text_field :username, required: true, autofocus: true, class: 'form-control' - .form-group - .col-md-4.control-label - = f.label :plain_text_password, nil, class: 'required' - .col-md-7 - = f.text_field :plain_text_password, required: true, class: 'form-control' - - .form-group - .col-md-4.control-label - = f.label :identity_code - .col-md-7 - = f.text_field(:identity_code, class: 'form-control') - - .form-group - .form-group.has-feedback.js-typeahead-container - .col-md-4.control-label - = f.label :registrar_typeahead, t(:registrar_name), class: 'required' - .col-md-7 - = f.text_field(:registrar_typeahead, - class: 'form-control js-registrar-typeahead typeahead required', - placeholder: t(:registrar_name), autocomplete: 'off') - %span.glyphicon.glyphicon-ok.form-control-feedback.js-typeahead-ok.hidden - %span.glyphicon.glyphicon-remove.form-control-feedback.js-typeahead-remove - = f.hidden_field(:registrar_id, class: 'js-registrar-id') - - .form-group - .col-md-4.control-label - = f.label :role, nil, class: 'required' - .col-md-7 - = select_tag 'api_user[roles][]', - options_for_select(ApiUser::ROLES.map {|x| [x, x] }, @api_user.roles.try(:first)), - class: 'form-control selectize' - .checkbox - %label{for: 'api_user_active'} - = f.check_box(:active) - = t('.active') - - %hr - - .row - .col-md-8.text-right - = button_tag(t(:save), class: 'btn btn-primary') - -:javascript - window.addEventListener('load', function() { - Autocomplete.bindAdminRegistrarSearch(); - }); diff --git a/app/views/admin/api_users/_form.html.erb b/app/views/admin/api_users/_form.html.erb new file mode 100644 index 000000000..ad6ee6b2b --- /dev/null +++ b/app/views/admin/api_users/_form.html.erb @@ -0,0 +1,58 @@ +<%= form_for([:admin, @api_user.registrar, @api_user], html: { class: 'form-horizontal', autocomplete: 'off' }) do |f| %> + <%= render 'form_errors', target: @api_user %> + +
+
+
+
+ <%= f.label :username, nil, class: 'required' %> +
+
+ <%= f.text_field :username, required: true, autofocus: true, class: 'form-control' %> +
+
+ +
+
+ <%= f.label :plain_text_password, nil, class: 'required' %> +
+
+ <%= f.text_field :plain_text_password, required: true, class: 'form-control' %> +
+
+ +
+
+ <%= f.label :identity_code %> +
+
+ <%= f.text_field(:identity_code, class: 'form-control') %> +
+
+ +
+
+ <%= f.label :roles, nil, for: nil, class: 'required' %> +
+ +
+ <%= select_tag 'api_user[roles][]', options_for_select(ApiUser::ROLES.map { |x| [x, x] }, @api_user.roles.try(:first)), class: 'form-control selectize' %> +
+ +
+
+
+
+
+ +
+ +
+
+ <%= button_tag t(".#{f.object.new_record? ? 'create' : 'update'}_btn"), class: 'btn btn-success' %> +
+
+<% end %> diff --git a/app/views/admin/api_users/edit.haml b/app/views/admin/api_users/edit.haml deleted file mode 100644 index 867d084d5..000000000 --- a/app/views/admin/api_users/edit.haml +++ /dev/null @@ -1,5 +0,0 @@ -- content_for :actions do - = link_to(t(:back_to_api_user), [:admin, @api_user], class: 'btn btn-default') -= render 'shared/title', name: "#{t(:edit)}: #{@api_user.username}" - -= render 'form' diff --git a/app/views/admin/api_users/edit.html.erb b/app/views/admin/api_users/edit.html.erb new file mode 100644 index 000000000..d065c885c --- /dev/null +++ b/app/views/admin/api_users/edit.html.erb @@ -0,0 +1,14 @@ + + + + +<%= render 'form' %> diff --git a/app/views/admin/api_users/index.haml b/app/views/admin/api_users/index.haml deleted file mode 100644 index 4815607a7..000000000 --- a/app/views/admin/api_users/index.haml +++ /dev/null @@ -1,25 +0,0 @@ -- content_for :actions do - = link_to(t('.new_btn'), new_admin_api_user_path, class: 'btn btn-primary') -= render 'shared/title', name: t('.title') - -.row - .col-md-12 - .table-responsive - %table.table.table-hover.table-bordered.table-condensed - %thead - %tr - %th{class: 'col-xs-2'} - = sort_link(@q, 'username') - %th{class: 'col-xs-2'} - = sort_link(@q, 'registrar_name', t(:registrar_name)) - %th{class: 'col-xs-2'} - = sort_link(@q, 'active', t('.active')) - %tbody - - @api_users.each do |x| - %tr - %td= link_to(x, [:admin, x]) - %td= link_to(x.registrar, [:admin, x.registrar]) - %td= x.active -.row - .col-md-12 - = paginate @api_users diff --git a/app/views/admin/api_users/index.html.erb b/app/views/admin/api_users/index.html.erb new file mode 100644 index 000000000..9c00f32d6 --- /dev/null +++ b/app/views/admin/api_users/index.html.erb @@ -0,0 +1,35 @@ + + +
+
+
+ + + + + + + + + + + <%= render @api_users %> + +
+ <%= sort_link(@q, 'username') %> + + <%= sort_link(@q, 'registrar_name', Registrar.model_name.human) %> + + <%= sort_link(@q, 'active', ApiUser.human_attribute_name(:active)) %> +
+
+
+
+ +
+
+ <%= paginate @api_users %> +
+
diff --git a/app/views/admin/api_users/new.haml b/app/views/admin/api_users/new.haml deleted file mode 100644 index f8282f44f..000000000 --- a/app/views/admin/api_users/new.haml +++ /dev/null @@ -1,3 +0,0 @@ -= render 'shared/title', name: t('.title') - -= render 'form' diff --git a/app/views/admin/api_users/new.html.erb b/app/views/admin/api_users/new.html.erb new file mode 100644 index 000000000..b3f4580e1 --- /dev/null +++ b/app/views/admin/api_users/new.html.erb @@ -0,0 +1,11 @@ + + + + +<%= render 'form' %> diff --git a/app/views/admin/api_users/show.haml b/app/views/admin/api_users/show.haml deleted file mode 100644 index 2e13445d1..000000000 --- a/app/views/admin/api_users/show.haml +++ /dev/null @@ -1,61 +0,0 @@ -- content_for :actions do - = link_to(t(:edit), edit_admin_api_user_path(@api_user), class: 'btn btn-default') - = link_to(t(:delete), admin_api_user_path(@api_user), - method: :delete, data: { confirm: t(:are_you_sure) }, class: 'btn btn-danger') -= render 'shared/title', name: @api_user.username - -- if @api_user.errors.any? - - @api_user.errors.each do |attr, err| - = err - %br -- if @api_user.errors.any? - %hr -.row - .col-md-12 - .panel.panel-default - .panel-heading - %h3.panel-title= t(:general) - .panel-body - %dl.dl-horizontal - %dt= t(:username) - %dd= @api_user.username - - %dt= t(:password) - %dd= @api_user.plain_text_password - - %dt= t(:registrar_name) - %dd= link_to(@api_user.registrar, admin_registrar_path(@api_user.registrar)) - - %dt= t(:role) - %dd= @api_user.roles.join(', ') - - %dt= t('.active') - %dd= @api_user.active -.row - .col-md-12 - .panel.panel-default - .panel-heading.clearfix - .pull-left - = t(:certificates) - .pull-right - = link_to(t(:upload_crt), - new_admin_api_user_certificate_path(@api_user, crt: true), class: 'btn btn-primary btn-xs') - = link_to(t(:upload_csr), - new_admin_api_user_certificate_path(@api_user), class: 'btn btn-primary btn-xs') - - .table-responsive - %table.table.table-hover.table-bordered.table-condensed - %thead - %tr - %th{class: 'col-xs-10'}= t('.subject') - %th{class: 'col-xs-2'}= t(:status) - %tbody - - @api_user.certificates.each do |x| - - if x.csr - %tr - %td= link_to(x.parsed_csr.try(:subject), admin_api_user_certificate_path(@api_user, x)) - %td= x.status - - elsif x.crt - %tr - %td= link_to(x.parsed_crt.try(:subject), admin_api_user_certificate_path(@api_user, x)) - %td= x.status diff --git a/app/views/admin/api_users/show.html.erb b/app/views/admin/api_users/show.html.erb new file mode 100644 index 000000000..05c5651ce --- /dev/null +++ b/app/views/admin/api_users/show.html.erb @@ -0,0 +1,37 @@ + + + + +
+
+ <%= render 'admin/api_users/show/details' %> +
+
+ +
+
+ <%= render 'admin/api_users/show/certificates' %> +
+
diff --git a/app/views/admin/api_users/show/_certificates.html.erb b/app/views/admin/api_users/show/_certificates.html.erb new file mode 100644 index 000000000..75a3cc2df --- /dev/null +++ b/app/views/admin/api_users/show/_certificates.html.erb @@ -0,0 +1,55 @@ +
+
+
+ <%= t(:certificates) %> +
+ +
+ <%= link_to(t(:upload_crt), new_admin_api_user_certificate_path(@api_user, crt: true), class: 'btn btn-primary btn-xs') %> + <%= link_to(t(:upload_csr), new_admin_api_user_certificate_path(@api_user), class: 'btn btn-primary btn-xs') %> +
+
+ +
+ + + + + + + + + + <% @api_user.certificates.each do |x| %> + <% if x.csr %> + + + + + <% elsif x.crt %> + + + + + <% end %> + <% end %> + +
+ <%= t('.subject') %> + + <%= t(:status) %> +
+ <%= link_to(x.parsed_csr.try(:subject), + admin_api_user_certificate_path(@api_user, + x)) %> + + <%= x.status %> +
+ <%= link_to(x.parsed_crt.try(:subject), + admin_api_user_certificate_path(@api_user, + x)) %> + + <%= x.status %> +
+
+
diff --git a/app/views/admin/api_users/show/_details.html.erb b/app/views/admin/api_users/show/_details.html.erb new file mode 100644 index 000000000..c98f23866 --- /dev/null +++ b/app/views/admin/api_users/show/_details.html.erb @@ -0,0 +1,26 @@ +
+
+

+ <%= t '.header' %> +

+
+ +
+
+
<%= ApiUser.human_attribute_name :username %>
+
<%= @api_user.username %>
+ +
<%= ApiUser.human_attribute_name :plain_text_password %>
+
<%= @api_user.plain_text_password %>
+ +
<%= Registrar.model_name.human %>
+
<%= link_to(@api_user.registrar, admin_registrar_path(@api_user.registrar)) %>
+ +
<%= ApiUser.human_attribute_name :roles %>
+
<%= @api_user.roles.join(', ') %>
+ +
<%= ApiUser.human_attribute_name :active %>
+
<%= @api_user.active %>
+
+
+
diff --git a/app/views/admin/bank_statements/index.haml b/app/views/admin/bank_statements/index.haml index 0810c15fe..2c604c035 100644 --- a/app/views/admin/bank_statements/index.haml +++ b/app/views/admin/bank_statements/index.haml @@ -1,6 +1,6 @@ - content_for :actions do = link_to(t(:add), new_admin_bank_statement_path, class: 'btn btn-primary') - = link_to(t(:import), import_admin_bank_statements_path, class: 'btn btn-primary') + = link_to(t('.import_btn'), import_admin_bank_statements_path, class: 'btn btn-primary') = render 'shared/title', name: t(:bank_statements) .row diff --git a/app/views/admin/base/_menu.haml b/app/views/admin/base/_menu.haml index d99a1598c..a327419fd 100644 --- a/app/views/admin/base/_menu.haml +++ b/app/views/admin/base/_menu.haml @@ -6,8 +6,6 @@ %li= link_to t(:contacts), admin_contacts_path - if can? :show, Registrar %li= link_to t(:registrars), admin_registrars_path - - if can? :show, Keyrelay - %li= link_to t(:keyrelays), admin_keyrelays_path - if can?(:access, :settings_menu) %li.dropdown %a.dropdown-toggle{"data-toggle" => "dropdown", href: "#"} @@ -34,10 +32,11 @@ %li= link_to t('.zones'), admin_zones_path %li= link_to t('.blocked_domains'), admin_blocked_domains_path %li= link_to t('.reserved_domains'), admin_reserved_domains_path + %li= link_to t('.disputed_domains'), admin_disputes_path %li= link_to t('.epp_log'), admin_epp_logs_path(created_after: 'today') %li= link_to t('.repp_log'), admin_repp_logs_path(created_after: 'today') %li= link_to t('.que'), '/admin/que' %ul.nav.navbar-nav.navbar-right %li= link_to t('.sign_out'), destroy_admin_user_session_path, method: :delete, - class: 'navbar-link' \ No newline at end of file + class: 'navbar-link' diff --git a/app/views/admin/certificates/new.haml b/app/views/admin/certificates/new.haml index 40947ed19..e2988f58e 100644 --- a/app/views/admin/certificates/new.haml +++ b/app/views/admin/certificates/new.haml @@ -8,7 +8,7 @@ .form-group - if params[:crt] .col-md-4.control-label - = f.label :crt, t(:certificate) + = f.label :crt, t('.certificate_file') .col-md-8 = f.file_field :crt - else diff --git a/app/views/admin/certificates/show.haml b/app/views/admin/certificates/show.haml index 5adbdbdc4..30d095f65 100644 --- a/app/views/admin/certificates/show.haml +++ b/app/views/admin/certificates/show.haml @@ -20,7 +20,7 @@ .panel-body %dl.dl-horizontal %dt= t(:api_user) - %dd= link_to(@certificate.api_user, [:admin, @api_user]) + %dd= link_to(@certificate.api_user, [:admin, @api_user.registrar, @api_user]) %dt= t(:common_name) %dd= @certificate.common_name @@ -54,7 +54,7 @@ %dt= t(:version) %dd= @csr.version - %dt= t(:subject) + %dt= CertificationRequest.human_attribute_name :subject %dd= @csr.subject %dt= t(:signature_algorithm) @@ -78,7 +78,7 @@ %dt= t(:version) %dd= @crt.version - %dt= t(:serial_number) + %dt= Certificate.human_attribute_name :serial_number %dd= @crt.serial %dt= t(:signature_algorithm) @@ -93,8 +93,8 @@ %dt= t(:valid_to) %dd= @crt.not_after - %dt= t(:subject) + %dt= Certificate.human_attribute_name :subject %dd= @crt.subject - %dt= t(:extensions) + %dt= Certificate.human_attribute_name :extensions %dd= @crt.extensions.map(&:to_s).join('
').html_safe diff --git a/app/views/admin/contact_versions/show.haml b/app/views/admin/contact_versions/show.haml index a412b4312..901f5ee1a 100644 --- a/app/views/admin/contact_versions/show.haml +++ b/app/views/admin/contact_versions/show.haml @@ -106,4 +106,4 @@ = l(vs.created_at, format: :short) = vs.event %span{:style => "padding-left:10px; position: absolute; bottom: 10px;"} - = paginate @versions, theme: :admin + = paginate @versions diff --git a/app/views/admin/contacts/index.haml b/app/views/admin/contacts/index.haml index cc80ac744..cbd11d3fc 100644 --- a/app/views/admin/contacts/index.haml +++ b/app/views/admin/contacts/index.haml @@ -63,6 +63,10 @@ .form-group = label_tag :only_no_country_code, "Ident CC missing" = check_box_tag :only_no_country_code, '1',params[:only_no_country_code].eql?('1'), style: 'width:auto;height:auto;float:right' + .col-md-3 + .form-group + = label_tag :email_verification_failed, "Email verification failed" + = check_box_tag :email_verification_failed, '1',params[:email_verification_failed].eql?('1'), style: 'width:auto;height:auto;float:right' .row .col-md-3{style: 'padding-top: 25px;float:right;'} @@ -85,7 +89,9 @@ %th{class: 'col-xs-2'} = sort_link(@q, 'ident', t(:ident)) %th{class: 'col-xs-2'} - = sort_link(@q, 'email', t(:created_at)) + = sort_link(@q, 'email', t(:email)) + %th{class: 'col-xs-2'} + = sort_link(@q, 'created_at', t(:created_at)) %th{class: 'col-xs-2'} = sort_link(@q, 'registrar_name', t(:registrar_name)) %tbody @@ -94,6 +100,7 @@ %td= link_to(contact, admin_contact_path(contact)) %td= contact.code %td= ident_for(contact) + %td= verified_email_span(contact.email_verification) %td= l(contact.created_at, format: :short) %td - if contact.registrar diff --git a/app/views/admin/contacts/partials/_domains.haml b/app/views/admin/contacts/partials/_domains.haml index 9d7e3edf5..91b0715ba 100644 --- a/app/views/admin/contacts/partials/_domains.haml +++ b/app/views/admin/contacts/partials/_domains.haml @@ -1,5 +1,6 @@ -- domains = contact.all_domains(page: params[:domain_page], per: 20, params: params) -#contacts.panel.panel-default +- domains = contact.all_domains(page: params[:domain_page], per: 20, + params: domain_filter_params.to_h) +.panel.panel-default .panel-heading .pull-left = t(:domains) diff --git a/app/views/admin/contacts/partials/_general.haml b/app/views/admin/contacts/partials/_general.haml index 029f89509..6568cd3d0 100644 --- a/app/views/admin/contacts/partials/_general.haml +++ b/app/views/admin/contacts/partials/_general.haml @@ -17,7 +17,7 @@ %dd= ident_for(@contact) %dt= t(:email) - %dd= @contact.email + %dd= verified_email_span(@contact.email_verification) %dt= t(:phone) %dd= @contact.phone diff --git a/app/views/admin/contacts/partials/_statuses.haml b/app/views/admin/contacts/partials/_statuses.haml deleted file mode 100644 index c39075754..000000000 --- a/app/views/admin/contacts/partials/_statuses.haml +++ /dev/null @@ -1,21 +0,0 @@ -- panel_class = contact.errors.messages[:statuses] ? 'panel-danger' : 'panel-default' -#contact_statuses.panel{class: panel_class} - .panel-heading.clearfix - = t(:statuses) - .table-responsive - %table.table.table-hover.table-bordered.table-condensed - %thead - %tr - %th{class: 'col-xs-6'}= t(:status) - %th{class: 'col-xs-6'}= t(:notes) - %tbody - - contact.statuses.each do |status| - %tr - %td= status - %td= contact.status_notes[status] - - - if contact.errors.messages[:statuses] - %tfoot - - @domain.errors.messages[:statuses].each do |s| - %tr - %td{colspan: 4}= s diff --git a/app/views/admin/contacts/partials/_statuses.html.erb b/app/views/admin/contacts/partials/_statuses.html.erb new file mode 100644 index 000000000..2d1703c2c --- /dev/null +++ b/app/views/admin/contacts/partials/_statuses.html.erb @@ -0,0 +1,23 @@ +
+
+ <%= t '.header' %> +
+ + + + + + + + + + + <% contact.statuses.each do |status| %> + + + + + <% end %> + +
<%= t(:status) %><%= t(:notes) %>
<%= status %><%= contact.status_notes[status] %>
+
diff --git a/app/views/admin/disputes/_form.html.erb b/app/views/admin/disputes/_form.html.erb new file mode 100644 index 000000000..2a3fb722f --- /dev/null +++ b/app/views/admin/disputes/_form.html.erb @@ -0,0 +1,60 @@ +<%= form_for([:admin, @dispute], html: { class: 'form-horizontal' }) do |f| %> + <%= render 'shared/full_errors', object: @dispute %> + +
+
+
+
+
+ <%= t(:general) %> +
+
+
+
+

As per domain law, expiry time is <%= Setting.dispute_period_in_months / 12 %> years ahead from start date.

+
+
+
+ <%= f.label :domain_name %> +
+
+ <%= f.text_field(:domain_name, class: 'form-control', disabled: !f.object.new_record?) %> +
+
+
+
+ <%= f.label :password %> +
+
+ <%= f.text_field(:password, placeholder: t(:optional), class: 'form-control') %> + <%= t '.password_hint' %> +
+
+
+
+ <%= f.label :starts_at %> +
+
+ <%= f.text_field(:starts_at, class: 'form-control js-datepicker') %> + <%= t '.past_or_today' %> +
+
+
+
+ <%= f.label :comment %> +
+
+ <%= f.text_field(:comment, placeholder: t(:optional), class: 'form-control') %> +
+
+
+
+
+
+ +
+
+ <%= button_tag(t(:save), class: 'btn btn-primary') %> +
+
+<% end %> diff --git a/app/views/admin/disputes/edit.haml b/app/views/admin/disputes/edit.haml new file mode 100644 index 000000000..966976891 --- /dev/null +++ b/app/views/admin/disputes/edit.haml @@ -0,0 +1,3 @@ += render 'shared/title', name: t(:edit_dispute) + += render 'form' diff --git a/app/views/admin/disputes/index.html.erb b/app/views/admin/disputes/index.html.erb new file mode 100644 index 000000000..e32ddb730 --- /dev/null +++ b/app/views/admin/disputes/index.html.erb @@ -0,0 +1,175 @@ +<% content_for :actions do %> +<%= link_to(t('.new_btn'), new_admin_dispute_path, class: 'btn btn-primary') %> +<% end %> +<%= render 'shared/title', name: t('.title') %> +
+
+ <%= search_form_for [:admin, @q], html: { style: 'margin-bottom: 0;', class: 'js-form', autocomplete: 'off' } do |f| %> +
+
+
+ <%= f.label :domain_name %> + <%= f.search_field :domain_name_matches, value: params[:q][:domain_name_matches], class: 'form-control', placeholder: t(:name) %> +
+
+
+
+ <%= f.label t(:created_at_from) %> + <%= f.search_field :created_at_gteq, value: params[:q][:created_at_gteq], class: 'form-control js-datepicker', placeholder: t(:created_at_from) %> +
+
+
+
+ <%= f.label t(:created_at_until) %> + <%= f.search_field :created_at_lteq, value: params[:q][:created_at_lteq], class: 'form-control js-datepicker', placeholder: t(:created_at_until) %> +
+
+
+
+
+
+ <%= label_tag t(:results_per_page) %> + <%= text_field_tag :results_per_page, params[:results_per_page], class: 'form-control', placeholder: t(:results_per_page) %> +
+
+
+ + <%= link_to(t('.reset_btn'), admin_disputes_path, class: 'btn btn-default') %> +
+
+ <% end %> +
+
+
+

Active disputes

+
+
+
+ + + + + + + + + + + + + <% @disputes.each do |x| %> + + + + + + + + + <% end %> + +
+ <%= sort_link(@q, 'domain_name') %> + + <%= sort_link(@q, 'password') %> + + <%= sort_link(@q, 'starts_at') %> + + <%= sort_link(@q, 'expires_at') %> + + <%= sort_link(@q, 'comment') %> + + <%= t(:actions) %> +
+ <%= x.domain_name %> + + <%= x.password %> + + <%= x.starts_at %> + + <%= x.expires_at %> + + <%= x.comment %> + + <%= link_to t(:edit), edit_admin_dispute_path(id: x.id), + class: 'btn btn-primary btn-xs' %> + <%= link_to t(:delete), delete_admin_dispute_path(id: x.id), + data: { confirm: t(:are_you_sure) }, class: 'btn btn-danger btn-xs' %> +
+
+
+
+
+
+ <%= paginate @disputes %> +
+
+ +
+
+
+

Expired / Closed disputes

+
+
+
+ + + + + + + + + + + + <% @closed_disputes.each do |x| %> + + + + + + + + <% end %> + +
+ <%= sort_link(@q, 'domain_name') %> + + <%= sort_link(@q, 'initiator') %> + + <%= sort_link(@q, 'starts_at') %> + + <%= sort_link(@q, 'closed') %> + + <%= sort_link(@q, 'comment') %> +
+ <%= x.domain_name %> + + <%= x.initiator %> + + <%= x.starts_at %> + + <%= x.closed %> + + <%= x.comment %> +
+
+
+
+
+
+ <%= paginate @closed_disputes, param_name: :closed_page %> +
+
+ +
+
diff --git a/app/views/admin/disputes/new.haml b/app/views/admin/disputes/new.haml new file mode 100644 index 000000000..0a57af7be --- /dev/null +++ b/app/views/admin/disputes/new.haml @@ -0,0 +1,3 @@ += render 'shared/title', name: t(:add_disputed_domain) + += render 'form' diff --git a/app/views/admin/domain_versions/show.haml b/app/views/admin/domain_versions/show.haml index 9a38150be..cb95f231c 100644 --- a/app/views/admin/domain_versions/show.haml +++ b/app/views/admin/domain_versions/show.haml @@ -129,4 +129,4 @@ = l(vs.created_at, format: :short) = vs.event %span{:style => "padding-left:10px; position: absolute; bottom: 10px;"} - = paginate @versions, theme: :admin + = paginate @versions diff --git a/app/views/admin/domains/_domain.html.erb b/app/views/admin/domains/_domain.html.erb index 6431833e6..8b69f9010 100644 --- a/app/views/admin/domains/_domain.html.erb +++ b/app/views/admin/domains/_domain.html.erb @@ -1,6 +1,6 @@ <%= link_to domain, admin_domain_path(domain) %> - <%= link_to domain.registrant, admin_registrant_path(domain.registrant) %> + <%= link_to domain.registrant, admin_contact_path(domain.registrant) %> <%= l domain.expire_time %> <%= link_to domain.registrar, admin_registrar_path(domain.registrar) %> diff --git a/app/views/admin/domains/_force_delete_dialog.html.erb b/app/views/admin/domains/_force_delete_dialog.html.erb index 26edf3756..a76c14edd 100644 --- a/app/views/admin/domains/_force_delete_dialog.html.erb +++ b/app/views/admin/domains/_force_delete_dialog.html.erb @@ -10,6 +10,17 @@ <%= form_tag admin_domain_force_delete_path(domain), id: 'domain-force-delete-form', class: 'modal-body form-horizontal' do %> +
+
+
+ +
+
+
+
diff --git a/app/views/admin/domains/partials/_admin_contacts.haml b/app/views/admin/domains/partials/_admin_contacts.haml index bf14bf1bb..8c293b469 100644 --- a/app/views/admin/domains/partials/_admin_contacts.haml +++ b/app/views/admin/domains/partials/_admin_contacts.haml @@ -1,4 +1,5 @@ -- panel_class = @domain.errors.messages[:admin_contacts] ? 'panel-danger' : 'panel-default' +- admin_contacts_invalid = @domain.errors.include?(:admin_contacts) +- panel_class = admin_contacts_invalid ? 'panel-danger' : 'panel-default' .panel{class: panel_class} .panel-heading.clearfix = t('.title') @@ -15,7 +16,7 @@ %td= link_to(ac, admin_contact_path(ac)) %td= ac.code %td= ac.email - - if @domain.errors.messages[:admin_contacts] + - if admin_contacts_invalid %tfoot - @domain.errors.messages[:admin_contacts].each do |x| %tr diff --git a/app/views/admin/domains/partials/_dnskeys.haml b/app/views/admin/domains/partials/_dnskeys.haml index 6d5759e65..ddd95e952 100644 --- a/app/views/admin/domains/partials/_dnskeys.haml +++ b/app/views/admin/domains/partials/_dnskeys.haml @@ -1,5 +1,4 @@ -- panel_class = @domain.errors.messages[:dnskeys] ? 'panel-danger' : 'panel-default' -#dnskeys.panel{class: panel_class} +.panel.panel-default .panel-heading.clearfix = t(:dnskeys) .table-responsive @@ -17,9 +16,3 @@ %td= x.protocol %td= x.alg %td= x.public_key - - if @domain.errors.messages[:dnskeys] - %tfoot - - @domain.errors.messages[:dnskeys].each do |x| - %tr - %td{colspan: 4}= x - diff --git a/app/views/admin/domains/partials/_keyrelays.haml b/app/views/admin/domains/partials/_keyrelays.haml deleted file mode 100644 index 43d099383..000000000 --- a/app/views/admin/domains/partials/_keyrelays.haml +++ /dev/null @@ -1,20 +0,0 @@ -.panel{class: 'panel-default'} - .panel-heading.clearfix - = t(:keyrelays) - .table-responsive - %table.table.table-hover.table-bordered.table-condensed - %thead - %tr - %th{class: 'col-xs-4'}= t(:uploaded_at) - %th{class: 'col-xs-3'}= t(:expiry) - %th{class: 'col-xs-2'}= t(:requester) - %th{class: 'col-xs-2'}= t(:accepter) - %th{class: 'col-xs-1'}= t(:status) - %tbody - - @domain.keyrelays.includes([:requester, :accepter]).order(pa_date: :desc).each do |x| - %tr - %td= link_to(x.pa_date, [:admin, x]) - %td= x.expiry - %td= link_to(x.requester, [:admin, x.requester]) - %td= link_to(x.accepter, [:admin, x.accepter]) - %td= x.status diff --git a/app/views/admin/domains/partials/_nameservers.haml b/app/views/admin/domains/partials/_nameservers.haml index db3ca759a..0bc22732d 100644 --- a/app/views/admin/domains/partials/_nameservers.haml +++ b/app/views/admin/domains/partials/_nameservers.haml @@ -1,5 +1,4 @@ -- panel_class = @domain.errors.messages[:nameservers] ? 'panel-danger' : 'panel-default' -#nameservers.panel{class: panel_class} +.panel.panel-default .panel-heading.clearfix = t(:nameservers) .table-responsive @@ -15,9 +14,3 @@ %td= x %td= x.ipv4 %td= x.ipv6 - - if @domain.errors.messages[:nameservers] - %tfoot - - @domain.errors.messages[:nameservers].each do |x| - %tr - %td{colspan: 3}= x - diff --git a/app/views/admin/domains/partials/_owner.haml b/app/views/admin/domains/partials/_owner.haml index 611cd7dc6..f91cd2177 100644 --- a/app/views/admin/domains/partials/_owner.haml +++ b/app/views/admin/domains/partials/_owner.haml @@ -4,7 +4,7 @@ .panel-body %dl.dl-horizontal %dt= t(:name) - %dd= link_to(@domain.registrant, [:admin, @domain.registrant]) + %dd= link_to @domain.registrant, admin_contact_path(@domain.registrant) %dt= t(:id) %dd= @domain.registrant.code diff --git a/app/views/admin/domains/partials/_tech_contacts.haml b/app/views/admin/domains/partials/_tech_contacts.haml index c3109bc57..dbb4ecd12 100644 --- a/app/views/admin/domains/partials/_tech_contacts.haml +++ b/app/views/admin/domains/partials/_tech_contacts.haml @@ -1,5 +1,6 @@ -- panel_class = @domain.errors.messages[:tech_contacts] ? 'panel-danger' : 'panel-default' -#tech_contacts.panel{class: panel_class} +- tech_contacts_invalid = @domain.errors.include?(:tech_contacts) +- panel_class = tech_contacts_invalid ? 'panel-danger' : 'panel-default' +.panel{class: panel_class} .panel-heading.clearfix = t('.title') .table-responsive @@ -15,7 +16,7 @@ %td= link_to(tc, admin_contact_path(tc)) %td= tc.code %td= tc.email - - if @domain.errors.messages[:tech_contacts] + - if tech_contacts_invalid %tfoot - @domain.errors.messages[:tech_contacts].each do |x| %tr diff --git a/app/views/admin/domains/show.html.erb b/app/views/admin/domains/show.html.erb index 1501b35bb..2b2835429 100644 --- a/app/views/admin/domains/show.html.erb +++ b/app/views/admin/domains/show.html.erb @@ -57,12 +57,6 @@
-
-
- <%= render 'admin/domains/partials/keyrelays' %> -
-
-
<%= render 'admin/domains/partials/legal_documents', legal_documents: diff --git a/app/views/admin/epp_logs/index.haml b/app/views/admin/epp_logs/index.haml index 4909eb29e..ee62c4218 100644 --- a/app/views/admin/epp_logs/index.haml +++ b/app/views/admin/epp_logs/index.haml @@ -8,10 +8,10 @@ .col-md-3 .form-group = f.label :request_command - = f.select :request_command_eq, [[t(:choose),''], 'hello', 'login', 'logout', 'info', 'create', 'update', 'delete', 'check', 'renew', 'transfer', 'poll', 'keyrelay'], {}, class: 'form-control selectize', placeholder: t(:choose) + = f.select :request_command_eq, [[t(:choose),''], 'hello', 'login', 'logout', 'info', 'create', 'update', 'delete', 'check', 'renew', 'transfer', 'poll'], {}, class: 'form-control selectize', placeholder: t(:choose) .col-md-3 .form-group - - opts = [[t(:choose),''], 'contact', 'domain', 'poll', 'keyrelay'] + - opts = [[t(:choose),''], 'contact', 'domain', 'poll'] - opts += [params[:q][:request_object_cont]] if params[:q].present? && params[:q][:request_object_cont].present? = f.label :request_object = f.select :request_object_cont, opts, {}, class: 'form-control selectize_create', placeholder: t(:choose) diff --git a/app/views/admin/invoices/show.haml b/app/views/admin/invoices/show.haml index e3627c158..d0450469f 100644 --- a/app/views/admin/invoices/show.haml +++ b/app/views/admin/invoices/show.haml @@ -21,3 +21,5 @@ .col-md-6= render 'registrar/invoices/partials/buyer' .row .col-md-12= render 'registrar/invoices/partials/items' +.row + .col-md-12= render 'registrar/invoices/partials/payment_orders' diff --git a/app/views/admin/keyrelays/index.haml b/app/views/admin/keyrelays/index.haml deleted file mode 100644 index 04c8e6d1b..000000000 --- a/app/views/admin/keyrelays/index.haml +++ /dev/null @@ -1,42 +0,0 @@ -= render 'shared/title', name: t(:keyrelays) - -.row - .col-md-12 - = search_form_for [:admin, @q], html: { class: 'form-horizontal' } do |f| - .col-md-11 - .form-group - = f.search_field :domain_name_cont, class: 'form-control', placeholder: t(:domain_name) - .col-md-1.text-right.text-center-xs - .form-group - %button.btn.btn-primary -   - %span.glyphicon.glyphicon-search -   -%hr -.row - .col-md-12 - .table-responsive - %table.table.table-hover.table-bordered.table-condensed - %thead - %tr - %th{class: 'col-xs-4'} - = sort_link(@q, 'pa_date', t(:uploaded_at)) - %th{class: 'col-xs-3'} - = t(:expiry) - %th{class: 'col-xs-2'} - = sort_link(@q, 'requester_name', t(:requester)) - %th{class: 'col-xs-2'} - = sort_link(@q, 'accepter_name', t(:accepter)) - %th{class: 'col-xs-1'} - = t(:status) - %tbody - - @keyrelays.each do |x| - %tr - %td= link_to(x.pa_date, [:admin, x]) - %td= x.expiry - %td= link_to(x.requester, [:admin, x.requester]) - %td= link_to(x.accepter, [:admin, x.accepter]) - %td= x.status -.row - .col-md-12 - = paginate @keyrelays diff --git a/app/views/admin/keyrelays/show.haml b/app/views/admin/keyrelays/show.haml deleted file mode 100644 index 08f8b6f33..000000000 --- a/app/views/admin/keyrelays/show.haml +++ /dev/null @@ -1,61 +0,0 @@ -= render 'shared/title', name: t(:keyrelay_details) - -.row - .col-md-12 - .panel.panel-default - .panel-heading - %h3.panel-title= t(:keyrelay) - .panel-body{style: 'word-wrap: break-word;'} - %dl.dl-horizontal - %dt= t(:uploaded_at) - %dd= @keyrelay.pa_date - - %dt= t(:domain) - %dd= link_to(@keyrelay.domain, [:admin, @keyrelay.domain]) - - %dt= t(:status) - %dd= @keyrelay.status - - %dt= t(:flag) - %dd= @keyrelay.key_data_flags - - %dt= t(:protocol) - %dd= @keyrelay.key_data_protocol - - %dt= t(:algorithm) - %dd= @keyrelay.key_data_alg - - %dt= t(:public_key) - %dd= @keyrelay.key_data_public_key - - %dt= t(:authinfo_pw) - %dd= @keyrelay.auth_info_pw - - %dt= t(:expiry_relative) - %dd= @keyrelay.expiry_relative - - %dt= t(:expiry_absolute) - %dd= @keyrelay.expiry_absolute - - %dt= t(:requester) - %dd= link_to(@keyrelay.requester, [:admin, @keyrelay.requester]) - - %dt= t(:accepter) - %dd= link_to(@keyrelay.accepter, [:admin, @keyrelay.accepter]) - -.row - .col-md-12 - .panel.panel-default - .panel-heading.clearfix - = t(:legal_documents) - .table-responsive - %table.table.table-hover.table-bordered.table-condensed - %thead - %tr - %th{class: 'col-xs-8'}= t(:created_at) - %th{class: 'col-xs-4'}= t(:type) - %tbody - - @keyrelay.legal_documents.each do |x| - %tr - %td= link_to(x.created_at, [:admin, x]) - %td= x.document_type diff --git a/app/views/admin/registrars/_form.html.erb b/app/views/admin/registrars/_form.html.erb index 5545adef1..19866a31f 100644 --- a/app/views/admin/registrars/_form.html.erb +++ b/app/views/admin/registrars/_form.html.erb @@ -91,6 +91,24 @@ <%= f.check_box :test_registrar, class: 'form-control' %>
+ +
+
+ <%= f.label t('.legaldoc_optout') %> +
+
+ <%= f.check_box :legaldoc_optout, class: 'form-control' %> +
+
+ +
+
+ <%= f.label t('.legaldoc_optout_comment') %> +
+
+ <%= f.text_area :legaldoc_optout_comment, class: 'form-control', rows: 3 %> +
+
diff --git a/app/views/admin/registrars/form/_billing.html.erb b/app/views/admin/registrars/form/_billing.html.erb index 91086918b..e3bb6629e 100644 --- a/app/views/admin/registrars/form/_billing.html.erb +++ b/app/views/admin/registrars/form/_billing.html.erb @@ -47,6 +47,7 @@
<%= f.email_field :billing_email, class: 'form-control' %> + <%= t '.billing_email_hint' %>
diff --git a/app/views/admin/registrars/index.html.erb b/app/views/admin/registrars/index.html.erb index a66816568..e641f5294 100644 --- a/app/views/admin/registrars/index.html.erb +++ b/app/views/admin/registrars/index.html.erb @@ -28,6 +28,9 @@ <%= t(:test_registrar) %> + + <%= t(:emails) %> + @@ -45,6 +48,12 @@ <%= "#{x.test_registrar}" %> + + <%= verified_email_span(x.email_verification) %> + <% if x[:billing_email].present? %> + <%= verified_email_span(x.billing_email_verification) %> + <% end %> + <% end %> diff --git a/app/views/admin/registrars/show.html.erb b/app/views/admin/registrars/show.html.erb index 62e7a5df1..2da2c84ce 100644 --- a/app/views/admin/registrars/show.html.erb +++ b/app/views/admin/registrars/show.html.erb @@ -39,7 +39,7 @@
- <%= render 'admin/registrars/show/users', registrar: @registrar %> + <%= render 'admin/registrars/show/api_users', registrar: @registrar %>
diff --git a/app/views/admin/registrars/show/_users.html.erb b/app/views/admin/registrars/show/_api_users.html.erb similarity index 76% rename from app/views/admin/registrars/show/_users.html.erb rename to app/views/admin/registrars/show/_api_users.html.erb index f182e4615..2d10b1c56 100644 --- a/app/views/admin/registrars/show/_users.html.erb +++ b/app/views/admin/registrars/show/_api_users.html.erb @@ -12,10 +12,10 @@ - <% registrar.api_users.each do |user| %> + <% registrar.api_users.each do |api_user| %> - <%= link_to(user, [:admin, user]) %> - <%= user.active %> + <%= link_to api_user, admin_registrar_api_user_path(api_user.registrar, api_user) %> + <%= api_user.active %> <% end %> diff --git a/app/views/admin/registrars/show/_billing.html.erb b/app/views/admin/registrars/show/_billing.html.erb index da79b9074..07bccc7f4 100644 --- a/app/views/admin/registrars/show/_billing.html.erb +++ b/app/views/admin/registrars/show/_billing.html.erb @@ -15,7 +15,9 @@
<%= registrar.accounting_customer_code %>
<%= Registrar.human_attribute_name :billing_email %>
-
<%= registrar.billing_email %>
+
+ <%= verified_email_span(registrar.billing_email_verification) %> +
<%= Registrar.human_attribute_name :reference_no %>
<%= registrar.reference_no %>
@@ -24,4 +26,4 @@
<%= registrar.iban %>
- \ No newline at end of file + diff --git a/app/views/admin/registrars/show/_contacts.html.erb b/app/views/admin/registrars/show/_contacts.html.erb index f467e6a51..0ca1158d3 100644 --- a/app/views/admin/registrars/show/_contacts.html.erb +++ b/app/views/admin/registrars/show/_contacts.html.erb @@ -15,7 +15,9 @@
<%= @registrar.phone %>
<%= Registrar.human_attribute_name :email %>
-
<%= @registrar.email %>
+
+ <%= verified_email_span(@registrar.email_verification) %> +
- \ No newline at end of file + diff --git a/app/views/admin/sessions/new.html.erb b/app/views/admin/sessions/new.html.erb index c875c00ce..e3e347177 100644 --- a/app/views/admin/sessions/new.html.erb +++ b/app/views/admin/sessions/new.html.erb @@ -16,14 +16,8 @@ required: true, class: 'form-control' %> - <% if devise_mapping.rememberable? -%> -
- -
- <% end -%> - <%= f.submit t('.sign_in_btn'), class: 'btn btn-lg btn-primary btn-block' %> <% end %> -<%= render 'links' %> \ No newline at end of file +<%= render 'links' %> diff --git a/app/views/admin/settings/_setting_row.haml b/app/views/admin/settings/_setting_row.haml index befd5b9d9..44078f32d 100644 --- a/app/views/admin/settings/_setting_row.haml +++ b/app/views/admin/settings/_setting_row.haml @@ -1,9 +1,8 @@ -- value = Setting.send(var) -%tr{class: (@errors && @errors.has_key?(var.to_s) && "danger")} - %td.col-md-6= var.to_s.humanize - - if [TrueClass, FalseClass].include?(value.class) +%tr{class: (@errors && @errors.has_key?(setting.code) && "danger")} + %td.col-md-6= setting.code.humanize + - if [TrueClass, FalseClass].include?(setting.retrieve.class) %td.col-md-6 - = hidden_field_tag("[settings][#{var}]", '', id: nil) - = check_box_tag("[settings][#{var}]", true, value) + = hidden_field_tag("[settings][#{setting.id}]", '', id: nil) + = check_box_tag("[settings][#{setting.id}]", true, setting.retrieve) - else - %td.col-md-6= text_field_tag("[settings][#{var}]", value, class: 'form-control') + %td.col-md-6= text_field_tag("[settings][#{setting.id}]", setting.value, class: 'form-control') diff --git a/app/views/admin/settings/index.haml b/app/views/admin/settings/index.haml index 23f87c4b2..c9a272a29 100644 --- a/app/views/admin/settings/index.haml +++ b/app/views/admin/settings/index.haml @@ -9,19 +9,8 @@ .table-responsive %table.table.table-hover.table-bordered.table-condensed %tbody - = render 'setting_row', var: :admin_contacts_min_count - = render 'setting_row', var: :admin_contacts_max_count - = render 'setting_row', var: :tech_contacts_min_count - = render 'setting_row', var: :tech_contacts_max_count - = render 'setting_row', var: :orphans_contacts_in_months - = render 'setting_row', var: :ds_data_allowed - = render 'setting_row', var: :key_data_allowed - = render 'setting_row', var: :dnskeys_min_count - = render 'setting_row', var: :dnskeys_max_count - = render 'setting_row', var: :nameserver_required - = render 'setting_row', var: :ns_min_count - = render 'setting_row', var: :ns_max_count - = render 'setting_row', var: :expire_pending_confirmation + - @validation_settings.each do |setting| + = render 'setting_row', setting: setting .panel.panel-default .panel-heading @@ -29,10 +18,8 @@ .table-responsive %table.table.table-hover.table-bordered.table-condensed %tbody - = render 'setting_row', var: :days_to_renew_domain_before_expire - = render 'setting_row', var: :expire_warning_period - = render 'setting_row', var: :redemption_grace_period - = render 'setting_row', var: :expiration_reminder_mail + - @expiration_settings.each do |setting| + = render 'setting_row', setting: setting .panel.panel-default .panel-heading @@ -40,19 +27,12 @@ .table-responsive %table.table.table-hover.table-bordered.table-condensed %tbody - = render 'setting_row', var: :transfer_wait_time - = render 'setting_row', var: :ds_digest_type - = render 'setting_row', var: :client_side_status_editing_enabled - = render 'setting_row', var: :api_ip_whitelist_enabled - = render 'setting_row', var: :registrar_ip_whitelist_enabled - = render 'setting_row', var: :request_confrimation_on_registrant_change_enabled - = render 'setting_row', var: :request_confirmation_on_domain_deletion_enabled - = render 'setting_row', var: :address_processing - + - @other_settings.each do |setting| + = render 'setting_row', setting: setting %tr %td.col-md-6= label_tag :default_language %td.col-md-6 - = select_tag '[settings][default_language]', + = select_tag "[settings][#{SettingEntry.find_by(code: 'default_language').id || 1}]", options_for_select(available_languages, Setting.default_language), class: 'form-control' @@ -62,25 +42,8 @@ .table-responsive %table.table.table-hover.table-bordered.table-condensed %tbody - = render 'setting_row', var: :invoice_number_min - = render 'setting_row', var: :invoice_number_max - = render 'setting_row', var: :directo_monthly_number_min - = render 'setting_row', var: :directo_monthly_number_max - = render 'setting_row', var: :directo_monthly_number_last - = render 'setting_row', var: :days_to_keep_invoices_active - = render 'setting_row', var: :days_to_keep_overdue_invoices_active - = render 'setting_row', var: :minimum_deposit - = render 'setting_row', var: :directo_receipt_payment_term - = render 'setting_row', var: :directo_receipt_product_name - = render 'setting_row', var: :directo_sales_agent - = render 'setting_row', var: :registry_billing_email - = render 'setting_row', var: :registry_invoice_contact - = render 'setting_row', var: :registry_vat_no - = render 'setting_row', var: :registry_vat_prc - = render 'setting_row', var: :registry_bank - = render 'setting_row', var: :registry_bank_code - = render 'setting_row', var: :registry_iban - = render 'setting_row', var: :registry_swift + - @billing_settings.each do |setting| + = render 'setting_row', setting: setting .panel.panel-default .panel-heading @@ -88,17 +51,8 @@ .table-responsive %table.table.table-hover.table-bordered.table-condensed %tbody - = render 'setting_row', var: :registry_juridical_name - = render 'setting_row', var: :registry_reg_no - = render 'setting_row', var: :registry_email - = render 'setting_row', var: :registry_phone - = render 'setting_row', var: :registry_url - = render 'setting_row', var: :registry_street - = render 'setting_row', var: :registry_city - = render 'setting_row', var: :registry_state - = render 'setting_row', var: :registry_zip - = render 'setting_row', var: :registry_country_code - = render 'setting_row', var: :registry_whois_disclaimer + - @contacts_settings.each do |setting| + = render 'setting_row', setting: setting .row .col-md-12.text-right diff --git a/app/views/epp/contacts/_disclosure_policy.xml.builder b/app/views/epp/contacts/_disclosure_policy.xml.builder deleted file mode 100644 index f3ba88159..000000000 --- a/app/views/epp/contacts/_disclosure_policy.xml.builder +++ /dev/null @@ -1,9 +0,0 @@ -if @disclosure_policy - @disclosure_policy.each do |k,v| - xml.tag!('contact:disclose', 'flag' => k) do - v.each do |attr| - xml.tag!("contact:#{attr}") - end - end - end -end diff --git a/app/views/epp/contacts/info.xml.builder b/app/views/epp/contacts/info.xml.builder index 068622203..1945e7def 100644 --- a/app/views/epp/contacts/info.xml.builder +++ b/app/views/epp/contacts/info.xml.builder @@ -65,17 +65,11 @@ xml.epp_head do xml.tag!('contact:upID', upID) if upID.present? # optional upID xml.tag!('contact:upDate', @contact.updated_at.try(:iso8601)) end - # xml.tag!('contact:trDate', '123') if false if can? :view_password, @contact, @password xml.tag!('contact:authInfo') do - xml.tag!('contact:pw', @contact.auth_info) - end - else - xml.tag!('contact:authInfo') do - xml.tag!('contact:pw', 'No access') + xml.tag!('contact:pw', @contact.auth_info) end end - # xml << render('/epp/contacts/disclosure_policy') end end if can? :view_full_info, @contact, @password diff --git a/app/views/epp/domains/info.xml.builder b/app/views/epp/domains/info.xml.builder index 937da30a4..ce5d60941 100644 --- a/app/views/epp/domains/info.xml.builder +++ b/app/views/epp/domains/info.xml.builder @@ -53,7 +53,7 @@ xml.epp_head do xml.tag!('domain:exDate', @domain.valid_to.iso8601) - if can? :view_password, @domain, @password + if @reveal_full_details xml.tag!('domain:authInfo') do xml.tag!('domain:pw', @domain.transfer_code) end diff --git a/app/views/epp/latin_error.xml.builder b/app/views/epp/latin_error.xml.builder deleted file mode 100644 index 6ff19efbf..000000000 --- a/app/views/epp/latin_error.xml.builder +++ /dev/null @@ -1,8 +0,0 @@ -xml.epp_head do - xml.response do - xml.result('code' => '2306') do - xml.msg('Parameter value policy error. Allowed only Latin characters.', 'lang' => 'en') - end - render('epp/shared/trID', builder: xml) - end -end diff --git a/app/views/epp/poll/poll_keyrelay.xml.builder b/app/views/epp/poll/poll_keyrelay.xml.builder deleted file mode 100644 index c5415273a..000000000 --- a/app/views/epp/poll/poll_keyrelay.xml.builder +++ /dev/null @@ -1,49 +0,0 @@ -xml.instruct!(:xml, standalone: 'no') -xml.epp( - 'xmlns' => 'https://epp.tld.ee/schema/epp-ee-1.0.xsd', - 'xmlns:secDNS' => 'urn:ietf:params:xml:ns:secDNS-1.1', - 'xmlns:domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd', - 'xmlns:keyrelay' => 'urn:ietf:params:xml:ns:keyrelay-1.0' -) do - xml.response do - xml.result('code' => '1301') do - xml.msg 'Command completed successfully; ack to dequeue' - end - - xml.tag!('msgQ', 'count' => current_user.unread_notifications.count, 'id' => @notification.id) do - xml.qDate @notification.created_at.try(:iso8601) - xml.msg @notification.text - end - - xml.resData do - xml.tag!('keyrelay:response') do - xml.tag!('keyrelay:panData') do - xml.tag!('keyrelay:name', @object.domain_name) - xml.tag!('keyrelay:paDate', @object.pa_date.try(:iso8601)) - - xml.tag!('keyrelay:keyData') do - xml.tag!('secDNS:flags', @object.key_data_flags) - xml.tag!('secDNS:protocol', @object.key_data_protocol) - xml.tag!('secDNS:alg', @object.key_data_alg) - xml.tag!('secDNS:pubKey', @object.key_data_public_key) - end - - - xml.tag!('keyrelay:authInfo') do - xml.tag!('domain:pw', @object.auth_info_pw) - end - - xml.tag!('keyrelay:expiry') do - xml.tag!('keyrelay:relative', @object.expiry_relative) - xml.tag!('keyrelay:absolute', @object.expiry_absolute) - end - - xml.tag!('keyrelay:reID', @object.requester) - xml.tag!('keyrelay:acID', @object.accepter) - end - end - end - - render('epp/shared/trID', builder: xml) - end -end diff --git a/app/views/epp/sessions/greeting.xml.builder b/app/views/epp/sessions/greeting.xml.builder index 040ce7196..072d2ead1 100644 --- a/app/views/epp/sessions/greeting.xml.builder +++ b/app/views/epp/sessions/greeting.xml.builder @@ -8,7 +8,6 @@ xml.epp_head do xml.objURI 'https://epp.tld.ee/schema/domain-eis-1.0.xsd' xml.objURI 'https://epp.tld.ee/schema/contact-ee-1.1.xsd' xml.objURI 'urn:ietf:params:xml:ns:host-1.0' - xml.objURI 'urn:ietf:params:xml:ns:keyrelay-1.0' xml.svcExtension do xml.extURI 'urn:ietf:params:xml:ns:secDNS-1.1' xml.extURI 'https://epp.tld.ee/schema/eis-1.0.xsd' diff --git a/app/views/invoice/pdf.haml b/app/views/invoice/pdf.haml index 19778ec43..9f10acdad 100644 --- a/app/views/invoice/pdf.haml +++ b/app/views/invoice/pdf.haml @@ -174,14 +174,14 @@ %dt= t(:payment_term) %dd Prepayment - + %dt= t(:invoice_number) %dd= @invoice.number - if @invoice.description.present? %dt= t(:description) %dd=@invoice.description - + %dt= Invoice.human_attribute_name :reference_no %dd= @invoice.reference_no @@ -194,26 +194,26 @@ %dt= t(:reg_no) %dd= @invoice.buyer_reg_no + + - if @invoice.buyer_address.present? + %dt= Invoice.human_attribute_name :address + %dd= @invoice.buyer_address + + - if @invoice.buyer_country.present? + %dt= t(:country) + %dd= @invoice.buyer_country + + - if @invoice.buyer_phone.present? + %dt= t(:phone) + %dd= @invoice.buyer_phone + + - if @invoice.buyer_url.present? + %dt= t(:url) + %dd= @invoice.buyer_url - - if @invoice.buyer_address.present? - %dt= t(:address) - %dd= @invoice.buyer_address - - - if @invoice.buyer_country.present? - %dt= t(:country) - %dd= @invoice.buyer_country - - - if @invoice.buyer_phone.present? - %dt= t(:phone) - %dd= @invoice.buyer_phone - - - if @invoice.buyer_phone.present? - %dt= t(:url) - %dd= @invoice.buyer_url - - - if @invoice.buyer_email.present? - %dt= t(:email) - %dd= @invoice.buyer_email + - if @invoice.buyer_email.present? + %dt= t(:email) + %dd= @invoice.buyer_email .clear .row.pull-down diff --git a/app/views/kaminari/admin/_first_page.html.haml b/app/views/kaminari/admin/_first_page.html.haml deleted file mode 100644 index c5bbf13e1..000000000 --- a/app/views/kaminari/admin/_first_page.html.haml +++ /dev/null @@ -1,11 +0,0 @@ --# Link to the "First" page --# available local variables --# url: url to the first page --# current_page: a page object for the currently displayed page --# total_pages: total number of pages --# per_page: number of items to fetch per page --# remote: data-remote -%span.first - - param_name = current_page.instance_variable_get("@options")[:param_name] || Kaminari.config.param_name - - urlik = url_for( params.merge(param_name => 1, :only_path => true)) - = link_to_unless current_page.first?, t('views.pagination.first').html_safe, urlik, :remote => remote diff --git a/app/views/kaminari/admin/_gap.html.haml b/app/views/kaminari/admin/_gap.html.haml deleted file mode 100644 index dd5789cc1..000000000 --- a/app/views/kaminari/admin/_gap.html.haml +++ /dev/null @@ -1,8 +0,0 @@ --# Non-link tag that stands for skipped pages... --# available local variables --# current_page: a page object for the currently displayed page --# total_pages: total number of pages --# per_page: number of items to fetch per page --# remote: data-remote -%span.page.gap - = t('views.pagination.truncate').html_safe diff --git a/app/views/kaminari/admin/_last_page.html.haml b/app/views/kaminari/admin/_last_page.html.haml deleted file mode 100644 index cdddb9e7c..000000000 --- a/app/views/kaminari/admin/_last_page.html.haml +++ /dev/null @@ -1,9 +0,0 @@ --# Link to the "Last" page --# available local variables --# url: url to the last page --# current_page: a page object for the currently displayed page --# total_pages: total number of pages --# per_page: number of items to fetch per page --# remote: data-remote -%span.last - = link_to_unless current_page.last?, t('views.pagination.last').html_safe, url, :remote => remote diff --git a/app/views/kaminari/admin/_next_page.html.haml b/app/views/kaminari/admin/_next_page.html.haml deleted file mode 100644 index 2865dcd0c..000000000 --- a/app/views/kaminari/admin/_next_page.html.haml +++ /dev/null @@ -1,9 +0,0 @@ --# Link to the "Next" page --# available local variables --# url: url to the next page --# current_page: a page object for the currently displayed page --# total_pages: total number of pages --# per_page: number of items to fetch per page --# remote: data-remote -%span.next - = link_to_unless current_page.last?, t('views.pagination.next').html_safe, url, :rel => 'next', :remote => remote diff --git a/app/views/kaminari/admin/_page.html.haml b/app/views/kaminari/admin/_page.html.haml deleted file mode 100644 index d583c58f1..000000000 --- a/app/views/kaminari/admin/_page.html.haml +++ /dev/null @@ -1,12 +0,0 @@ --# Link showing page number --# available local variables --# page: a page object for "this" page --# url: url to this page --# current_page: a page object for the currently displayed page --# total_pages: total number of pages --# per_page: number of items to fetch per page --# remote: data-remote -%span{:class => "page#{' current' if page.current?}"} - - param_name = current_page.instance_variable_get("@options")[:param_name] || Kaminari.config.param_name - - urlik = url_for( params.merge(param_name => page.to_i, :only_path => true)) - = link_to_unless page.current?, page, urlik, {:remote => remote, :rel => page.next? ? 'next' : page.prev? ? 'prev' : nil} diff --git a/app/views/kaminari/admin/_paginator.html.haml b/app/views/kaminari/admin/_paginator.html.haml deleted file mode 100644 index 4f33e2dee..000000000 --- a/app/views/kaminari/admin/_paginator.html.haml +++ /dev/null @@ -1,18 +0,0 @@ --# The container tag --# available local variables --# current_page: a page object for the currently displayed page --# total_pages: total number of pages --# per_page: number of items to fetch per page --# remote: data-remote --# paginator: the paginator that renders the pagination tags inside -= paginator.render do - %nav.pagination - = first_page_tag unless current_page.first? - = prev_page_tag unless current_page.first? - - each_page do |page| - - if page.left_outer? || page.right_outer? || page.inside_window? - = page_tag page - - elsif !page.was_truncated? - = gap_tag - = next_page_tag unless current_page.last? - = last_page_tag unless current_page.last? diff --git a/app/views/kaminari/admin/_prev_page.html.haml b/app/views/kaminari/admin/_prev_page.html.haml deleted file mode 100644 index 3b565fa6f..000000000 --- a/app/views/kaminari/admin/_prev_page.html.haml +++ /dev/null @@ -1,11 +0,0 @@ --# Link to the "Previous" page --# available local variables --# url: url to the previous page --# current_page: a page object for the currently displayed page --# total_pages: total number of pages --# per_page: number of items to fetch per page --# remote: data-remote -%span.prev - - param_name = current_page.instance_variable_get("@options")[:param_name] || Kaminari.config.param_name - - urlik = url_for( params.merge(param_name => current_page.to_i - 1, :only_path => true)) - = link_to_unless current_page.first?, t('views.pagination.previous').html_safe, urlik, :rel => 'prev', :remote => remote diff --git a/app/views/layouts/admin/base.haml b/app/views/layouts/admin/base.haml index 792a8cc0b..928629ce6 100644 --- a/app/views/layouts/admin/base.haml +++ b/app/views/layouts/admin/base.haml @@ -32,5 +32,5 @@ .footer.text-right Version - = CURRENT_COMMIT_HASH + = current_commit_link = javascript_include_tag 'admin-manifest', async: true diff --git a/app/views/layouts/registrant/application.html.erb b/app/views/layouts/registrant/application.html.erb index 7873728d5..c5290b70f 100644 --- a/app/views/layouts/registrant/application.html.erb +++ b/app/views/layouts/registrant/application.html.erb @@ -41,7 +41,7 @@
Version - <%= CURRENT_COMMIT_HASH %> + <%= current_commit_link %>
diff --git a/app/views/layouts/registrar/base.html.erb b/app/views/layouts/registrar/base.html.erb index 4d4f1b972..5881dd400 100644 --- a/app/views/layouts/registrar/base.html.erb +++ b/app/views/layouts/registrar/base.html.erb @@ -54,7 +54,7 @@
Version - <%= CURRENT_COMMIT_HASH %> + <%= current_commit_link %>
diff --git a/app/views/layouts/registrar/sessions.html.erb b/app/views/layouts/registrar/sessions.html.erb index 3cb345ef9..ace645199 100644 --- a/app/views/layouts/registrar/sessions.html.erb +++ b/app/views/layouts/registrar/sessions.html.erb @@ -44,7 +44,7 @@
Version - <%= CURRENT_COMMIT_HASH %> + <%= current_commit_link %>
diff --git a/app/views/mailers/domain_delete_mailer/forced/legal_person.html.erb b/app/views/mailers/domain_delete_mailer/forced/legal_person.html.erb index 4a4877767..39bedde9b 100644 --- a/app/views/mailers/domain_delete_mailer/forced/legal_person.html.erb +++ b/app/views/mailers/domain_delete_mailer/forced/legal_person.html.erb @@ -2,11 +2,11 @@

Eesti Interneti Sihtasutusele on saanud teatavaks, et juriidiline isik registrikoodiga <%= @registrant.reg_no %> on äriregistrist kustutatud.

-

Kuna äriregistrist kustutatud juriidiline isik ei saa olla domeeni registreerijaks, algas domeeni <%= @domain.name %> suhtes <%= @redemption_grace_period %> päevane kustutusmenetlus. Menetluse käigus on domeen internetis kättesaadav.

+

Kuna äriregistrist kustutatud juriidiline isik ei saa olla domeeni registreerijaks, algas domeeni <%= @domain.name %> suhtes <%= @delete_period_length %> päevane kustutusmenetlus. Menetluse käigus on domeen <%= @expire_warning_period %> esimest päeva internetis kättesaadav.

Domeeni suhtes õigust omaval isikul on võimalus esitada domeeni <%= @domain.name %> registripidajale <%= @registrar.name %> domeeni üleandmise taotlus koos seda tõendava dokumendiga.

-

Kui üleandmine ei ole <%= @redemption_grace_period %> päeva jooksul toimunud, läheb domeen <%= @domain.name %> <%= @domain.force_delete_date %> domeenioksjonile .ee oksjonikeskkonda. Juhul kui domeenile <%= @domain.name %> ei tehta oksjonil 24h möödudes pakkumist, domeen vabaneb ja on registreerimiseks vabalt kättesaadav kõigile huvilistele. Muude võimalike oksjoni tulemuste kohta loe siit.

+

Kui üleandmine ei ole <%= @delete_period_length %> päeva jooksul toimunud, läheb domeen <%= @domain.name %> <%= @domain.force_delete_date %> domeenioksjonile .ee oksjonikeskkonda. Juhul kui domeenile <%= @domain.name %> ei tehta oksjonil 24h möödudes pakkumist, domeen vabaneb ja on registreerimiseks vabalt kättesaadav kõigile huvilistele. Muude võimalike oksjoni tulemuste kohta loe siit.

Lisaküsimuste korral võtke palun ühendust oma registripidajaga:

<%= render 'mailers/shared/registrar/registrar.et.html', registrar: @registrar %> @@ -19,11 +19,11 @@

Estonian Internet Foundation has learned that the legal person with registry code <%= @registrant.reg_no %> has been deleted from the Business Registry.

-

As a terminated legal person cannot be the registrant of a domain, a <%= @redemption_grace_period %>-day deletion process has started for the <%= @domain.name %> domain. The domain will remain available on the Internet during the deletion process.

+

As a terminated legal person cannot be the registrant of a domain, a <%= @delete_period_length %>-day deletion process has started for the <%= @domain.name %> domain. For the first <%= @expire_warning_period %> days the domain will remain available on the Internet during the deletion process.

The registrant holding a right to the domain name <%= @domain.name %> can submit a domain name transfer application to the registrar <%= @registrar.name %> with legal documentation.

-

If the transfer is not made within <%= @redemption_grace_period %> days, the domain <%= @domain.name %> will go to domain auction on <%= @domain.force_delete_date %> in the .ee auction portal. If no offer is made for the domain <%= @domain.name %> at auction within 24 hours, the domain will be released and made freely available for registration to anyone interested on a first-come, first-served basis. Read more about other potential auction results.

+

If the transfer is not made within <%= @delete_period_length %> days, the domain <%= @domain.name %> will go to domain auction on <%= @domain.force_delete_date %> in the .ee auction portal. If no offer is made for the domain <%= @domain.name %> at auction within 24 hours, the domain will be released and made freely available for registration to anyone interested on a first-come, first-served basis. Read more about other potential auction results.

Should you have additional questions, please contact your registrar:

<%= render 'mailers/shared/registrar/registrar.en.html', registrar: @registrar %> @@ -35,13 +35,13 @@

Целевому учреждению Eesti Internet (EIS) стало известно, что юридическое лицо с регистрационным кодом <%= @registrant.reg_no %> удалено из коммерческого реестра.

-

Поскольку удаленное из коммерческого регистра юридическое лицо не может являться регистрантом домена, начат <%= @redemption_grace_period %>-дневный процесс удаления домена <%= @domain.name %>. До завершения процесса домен доступен в Интернете.

+

Поскольку удаленное из коммерческого регистра юридическое лицо не может являться регистрантом домена, начат <%= @delete_period_length %>-дневный процесс удаления домена <%= @domain.name %>. Домен доступен в интернете на протяжении <%= @expire_warning_period %> дней после начала процесса удаления.

-

Лицо, обладающее правом на домен, может подать регистратору <%= @registrar.name %> домена <%= @domain.name %> ходатайство о передаче домена, представив вместе с ходатайством подтверждающие документы. Документы должны быть представлены регистратору в течение <%= @redemption_grace_period %> дней.

+

Лицо, обладающее правом на домен, может подать регистратору <%= @registrar.name %> домена <%= @domain.name %> ходатайство о передаче домена, представив вместе с ходатайством подтверждающие документы. Документы должны быть представлены регистратору в течение <%= @delete_period_length %> дней.

-

Если передача не состоится в течение <%= @redemption_grace_period %> дней, <%= @domain.force_delete_date %> домен <%= @domain.name %> отправится на доменный аукцион в аукционной среде .ee. Если в течение 24 часов в отношении домена <%= @domain.name %> не поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». Читайте о других возможных результатах аукциона.

+

Если передача не состоится в течение <%= @delete_period_length %> дней, <%= @domain.force_delete_date %> домен <%= @domain.name %> отправится на доменный аукцион в аукционной среде .ee. Если в течение 24 часов в отношении домена <%= @domain.name %> не поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». Читайте о других возможных результатах аукциона.

В случае возникновения дополнительных вопросов свяжитесь, пожалуйста, со своим регистратором: <%= render 'mailers/shared/registrar/registrar.ru.html', registrar: @registrar %>

-<%= render 'mailers/shared/signatures/signature.ru.html' %> \ No newline at end of file +<%= render 'mailers/shared/signatures/signature.ru.html' %> diff --git a/app/views/mailers/domain_delete_mailer/forced/legal_person.text.erb b/app/views/mailers/domain_delete_mailer/forced/legal_person.text.erb index 31d13b9f9..fb2bc5d6c 100644 --- a/app/views/mailers/domain_delete_mailer/forced/legal_person.text.erb +++ b/app/views/mailers/domain_delete_mailer/forced/legal_person.text.erb @@ -2,11 +2,11 @@ Lugupeetud domeeni <%= @domain.name %> registreerija/halduskontakt Eesti Interneti Sihtasutusele on saanud teatavaks, et juriidiline isik registrikoodiga <%= @registrant.reg_no %> on äriregistrist kustutatud. -Kuna äriregistrist kustutatud juriidiline isik ei saa olla domeeni registreerijaks, algas domeeni <%= @domain.name %> suhtes <%= @redemption_grace_period %> päevane kustutusmenetlus. Menetluse käigus on domeen internetis kättesaadav. +Kuna äriregistrist kustutatud juriidiline isik ei saa olla domeeni registreerijaks, algas domeeni <%= @domain.name %> suhtes <%= @delete_period_length %> päevane kustutusmenetlus. Menetluse käigus on domeen <%= @expire_warning_period %> esimest päeva internetis kättesaadav. Domeeni suhtes õigust omaval isikul on võimalus esitada domeeni <%= @domain.name %> registripidajale <%= @registrar.name %> domeeni üleandmise taotlus koos seda tõendava dokumendiga. -Kui üleandmine ei ole <%= @redemption_grace_period %> päeva jooksul toimunud, läheb domeen <%= @domain.name %> <%= @domain.force_delete_date %> domeenioksjonile .ee oksjonikeskkonda https://auction.internet.ee. Juhul kui domeenile <%= @domain.name %> ei tehta oksjonil 24h möödudes pakkumist, domeen vabaneb ja on registreerimiseks vabalt kättesaadav kõigile huvilistele. Muude võimalike oksjoni tulemuste kohta loe https://www.internet.ee/domeenid/domeenide-oksjonikeskkonna-kasutajatingimused#3-oksjonikeskkonna-enampakkumisel-osalemise-tingimused. +Kui üleandmine ei ole <%= @delete_period_length %> päeva jooksul toimunud, läheb domeen <%= @domain.name %> <%= @domain.force_delete_date %> domeenioksjonile .ee oksjonikeskkonda https://auction.internet.ee. Juhul kui domeenile <%= @domain.name %> ei tehta oksjonil 24h möödudes pakkumist, domeen vabaneb ja on registreerimiseks vabalt kättesaadav kõigile huvilistele. Muude võimalike oksjoni tulemuste kohta loe https://www.internet.ee/domeenid/domeenide-oksjonikeskkonna-kasutajatingimused#3-oksjonikeskkonna-enampakkumisel-osalemise-tingimused. Lisaküsimuste korral võtke palun ühendust oma registripidajaga: <%= render 'mailers/shared/registrar/registrar.et.text', registrar: @registrar %> @@ -19,11 +19,11 @@ Dear registrant/administrative contact of .ee domain, Estonian Internet Foundation has learned that the legal person with registry code <%= @registrant.reg_no %> has been deleted from the Business Registry. -As a terminated legal person cannot be the registrant of a domain, a <%= @redemption_grace_period %>-day deletion process has started for the <%= @domain.name %> domain. The domain will remain available on the Internet during the deletion process. +As a terminated legal person cannot be the registrant of a domain, a <%= @delete_period_length %>-day deletion process has started for the <%= @domain.name %> domain. For the first <%= @expire_warning_period %> days the domain will remain available on the Internet during the deletion process. The registrant holding a right to the domain name <%= @domain.name %> can submit a domain name transfer application to the registrar <%= @registrar.name %> with legal documentation. -If the transfer is not made within <%= @redemption_grace_period %> days, the domain <%= @domain.name %> will go to domain auction on <%= @domain.force_delete_date %> in the .ee auction portal https://auction.internet.ee. If no offer is made for the domain <%= @domain.name %> at auction within 24 hours, the domain will be released and made freely available for registration to anyone interested on a first-come, first-served basis. Read more about other potential auction results at https://www.internet.ee/domains/auction-environment-user-agreement#3-terms-and-conditions-for-participation-in-the-auction-of-the-auction-environment. +If the transfer is not made within <%= @delete_period_length %> days, the domain <%= @domain.name %> will go to domain auction on <%= @domain.force_delete_date %> in the .ee auction portal https://auction.internet.ee. If no offer is made for the domain <%= @domain.name %> at auction within 24 hours, the domain will be released and made freely available for registration to anyone interested on a first-come, first-served basis. Read more about other potential auction results at https://www.internet.ee/domains/auction-environment-user-agreement#3-terms-and-conditions-for-participation-in-the-auction-of-the-auction-environment. Should you have additional questions, please contact your registrar: <%= render 'mailers/shared/registrar/registrar.en.text', registrar: @registrar %> @@ -36,13 +36,13 @@ Should you have additional questions, please contact your registrar: Целевому учреждению Eesti Internet (EIS) стало известно, что юридическое лицо с регистрационным кодом <%= @registrant.reg_no %> удалено из коммерческого реестра. -Поскольку удаленное из коммерческого регистра юридическое лицо не может являться регистрантом домена, начат <%= @redemption_grace_period %>-дневный процесс удаления домена <%= @domain.name %>. До завершения процесса домен доступен в Интернете. +Поскольку удаленное из коммерческого регистра юридическое лицо не может являться регистрантом домена, начат <%= @delete_period_length %>-дневный процесс удаления домена <%= @domain.name %>. Домен доступен в интернете на протяжении <%= @expire_warning_period %> дней после начала процесса удаления.

-Лицо, обладающее правом на домен, может подать регистратору <%= @registrar.name %> домена <%= @domain.name %> ходатайство о передаче домена, представив вместе с ходатайством подтверждающие документы. Документы должны быть представлены регистратору в течение <%= @redemption_grace_period %> дней. +Лицо, обладающее правом на домен, может подать регистратору <%= @registrar.name %> домена <%= @domain.name %> ходатайство о передаче домена, представив вместе с ходатайством подтверждающие документы. Документы должны быть представлены регистратору в течение <%= @delete_period_length %> дней. -Если передача не состоится в течение <%= @redemption_grace_period %> дней, <%= @domain.force_delete_date %> домен <%= @domain.name %> отправится на доменный аукцион в аукционной среде .ee https://auction.internet.ee. Если в течение 24 часов в отношении домена <%= @domain.name %> не поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». О других возможных результатах аукциона читайте по ссылке https://www.internet.ee/domeny/dogovor-pol-zovatelya-aukcionnoj-sredy#3-usloviya-uchastiya-v-aukcione. +Если передача не состоится в течение <%= @delete_period_length %>дней, <%= @domain.force_delete_date %> домен <%= @domain.name %> отправится на доменный аукцион в аукционной среде .ee https://auction.internet.ee. Если в течение 24 часов в отношении домена <%= @domain.name %> не поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». О других возможных результатах аукциона читайте по ссылке https://www.internet.ee/domeny/dogovor-pol-zovatelya-aukcionnoj-sredy#3-usloviya-uchastiya-v-aukcione. В случае возникновения дополнительных вопросов свяжитесь, пожалуйста, со своим регистратором: <%= render 'mailers/shared/registrar/registrar.ru.text', registrar: @registrar %> -<%= render 'mailers/shared/signatures/signature.ru.text' %> \ No newline at end of file +<%= render 'mailers/shared/signatures/signature.ru.text' %> diff --git a/app/views/mailers/domain_delete_mailer/forced/private_person.html.erb b/app/views/mailers/domain_delete_mailer/forced/private_person.html.erb index 2a7144d2c..947ff5c2b 100644 --- a/app/views/mailers/domain_delete_mailer/forced/private_person.html.erb +++ b/app/views/mailers/domain_delete_mailer/forced/private_person.html.erb @@ -2,11 +2,11 @@

Eesti Interneti Sihtasutusele (EIS) on saanud teatavaks, et füüsiline isik isikukoodiga <%= @registrant.id_code %> on surnud ja sellest on möödunud vähemalt 6 kuud.

-

Kuna surnud isik ei saa olla domeeni registreerijaks, algas domeeni <%= @domain.name %> suhtes <%= @redemption_grace_period %> päevane kustutusmenetlus. Menetluse käigus on domeen internetis kättesaadav.

+

Kuna surnud isik ei saa olla domeeni registreerijaks, algas domeeni <%= @domain.name %> suhtes <%= @delete_period_length %> päevane kustutusmenetlus. Menetluse käigus on domeen <%= @expire_warning_period %> esimest päeva internetis kättesaadav.

-

Domeeni suhtes õigust omaval isikul on võimalus esitada domeeni <%= @domain.name %> registripidajale <%= @registrar.name %> domeeni üleandmise taotlus, millele tuleb lisada pärimisõiguse tõend. Dokumentatsioon tuleb esitada registripidajale <%= @redemption_grace_period %> päeva jooksul.

+

Domeeni suhtes õigust omaval isikul on võimalus esitada domeeni <%= @domain.name %> registripidajale <%= @registrar.name %> domeeni üleandmise taotlus, millele tuleb lisada pärimisõiguse tõend. Dokumentatsioon tuleb esitada registripidajale <%= @delete_period_length %> päeva jooksul.

-

Kui üleandmine ei ole <%= @redemption_grace_period %> päeva jooksul toimunud, läheb domeen <%= @domain.name %> <%= @domain.force_delete_date %> domeenioksjonile .ee oksjonikeskkonda. Juhul kui domeenile <%= @domain.name %> ei tehta oksjonil 24h möödudes pakkumist, domeen vabaneb ja on registreerimiseks vabalt kättesaadav kõigile huvilistele. Muude võimalike oksjoni tulemuste kohta loe siit.

+

Kui üleandmine ei ole <%= @delete_period_length %> päeva jooksul toimunud, läheb domeen <%= @domain.name %> <%= @domain.force_delete_date %> domeenioksjonile .ee oksjonikeskkonda. Juhul kui domeenile <%= @domain.name %> ei tehta oksjonil 24h möödudes pakkumist, domeen vabaneb ja on registreerimiseks vabalt kättesaadav kõigile huvilistele. Muude võimalike oksjoni tulemuste kohta loe siit.

Lisaküsimuste korral võtke palun ühendust oma registripidajaga:

<%= render 'mailers/shared/registrar/registrar.et.html', registrar: @registrar %> @@ -19,11 +19,11 @@

Estonian Internet Foundation (EIF) has learned that the natural person with identification code <%= @registrant.id_code %> has been deceased more than 6 months.

-

The registrant holding a right to the domain name <%= @domain.name %> can submit a domain name transfer application to the registrar <%= @registrar.name %>.The application must be submitted together with succession evidence certifying the acquisition of the domain. The relevant documents should be submitted to the registrar within <%= @redemption_grace_period %> days.

+

The registrant holding a right to the domain name <%= @domain.name %> can submit a domain name transfer application to the registrar <%= @registrar.name %>.The application must be submitted together with succession evidence certifying the acquisition of the domain. The relevant documents should be submitted to the registrar within <%= @delete_period_length %> days.

-

As a deceased natural person can not be the registrant of a domain, a <%= @redemption_grace_period %>-day deletion process of <%= @domain.name %> domain has started. The domain will remain available on the Internet during the deletion process.

+

As a deceased natural person can not be the registrant of a domain, a <%= @delete_period_length %>-day deletion process of <%= @domain.name %> domain has started. For the first <%= @expire_warning_period %> days the domain will remain available on the Internet during the deletion process.

-

If the transfer is not made within <%= @redemption_grace_period %> days, the domain <%= @domain.name %> will go to domain auction on <%= @domain.force_delete_date %> in the .ee auction environment. If no offer is made for the domain <%= @domain.name %> at auction within 24 hours, the domain will be released and made freely available for registration to anyone interested on a first-come, first-served basis. Read more about other potential auction results.

+

If the transfer is not made within <%= @delete_period_length %> days, the domain <%= @domain.name %> will go to domain auction on <%= @domain.force_delete_date %> in the .ee auction environment. If no offer is made for the domain <%= @domain.name %> at auction within 24 hours, the domain will be released and made freely available for registration to anyone interested on a first-come, first-served basis. Read more about other potential auction results.

Should you have additional questions, please contact your registrar:

<%= render 'mailers/shared/registrar/registrar.en.html', registrar: @registrar %> @@ -36,13 +36,13 @@

Целевому учреждению Eesti Internet (EIS) стало известно, что физическое лицо с личным кодом <%= @registrant.id_code %> умерло, и с момента смерти прошло не менее 6 месяцев.

-

Поскольку умершее лицо не может являться регистрантом домена, начат <%= @redemption_grace_period %>-дневный процесс удаления домена <%= @domain.name %>. До завершения процесса домен доступен в Интернете.

+

Поскольку умершее лицо не может являться регистрантом домена, начат <%= @delete_period_length %>-дневный процесс удаления домена <%= @domain.name %>. Домен доступен в интернете на протяжении <%= @expire_warning_period %> дней после начала процесса удаления.

-

Лицо, обладающее правом на домен, может подать регистратору <%= @registrar.name %> домена <%= @domain.name %> ходатайство о передаче, представив справку о праве наследования. Документы должны быть представлены регистратору в течение <%= @redemption_grace_period %> дней.

+

Лицо, обладающее правом на домен, может подать регистратору <%= @registrar.name %> домена <%= @domain.name %> ходатайство о передаче, представив справку о праве наследования. Документы должны быть представлены регистратору в течение <%= @delete_period_length %> дней.

-

Если передача не состоится в течение <%= @redemption_grace_period %> дней, <%= @domain.force_delete_date %> домен <%= @domain.name %> отправится на доменный аукцион в аукционной среде .ee. Если в течение 24 часов в отношении домена <%= @domain.name %> не поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». Читайте о других возможных результатах аукциона.

+

Если передача не состоится в течение <%= @delete_period_length %> дней, <%= @domain.force_delete_date %> домен <%= @domain.name %> отправится на доменный аукцион в аукционной среде .ee. Если в течение 24 часов в отношении домена <%= @domain.name %> не поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». Читайте о других возможных результатах аукциона.

В случае возникновения дополнительных вопросов свяжитесь, пожалуйста, со своим регистратором:

<%= render 'mailers/shared/registrar/registrar.ru.html', registrar: @registrar %> -<%= render 'mailers/shared/signatures/signature.ru.html' %> \ No newline at end of file +<%= render 'mailers/shared/signatures/signature.ru.html' %> diff --git a/app/views/mailers/domain_delete_mailer/forced/private_person.text.erb b/app/views/mailers/domain_delete_mailer/forced/private_person.text.erb index 9a8971b19..bb315e48b 100644 --- a/app/views/mailers/domain_delete_mailer/forced/private_person.text.erb +++ b/app/views/mailers/domain_delete_mailer/forced/private_person.text.erb @@ -2,11 +2,11 @@ Lugupeetud domeeni <%= @domain.name %> registreerija/halduskontakt Eesti Interneti Sihtasutusele (EIS) on saanud teatavaks, et füüsiline isik isikukoodiga <%= @registrant.id_code %> on surnud ja sellest on möödunud vähemalt 6 kuud. -Kuna surnud isik ei saa olla domeeni registreerijaks, algas domeeni <%= @domain.name %> suhtes <%= @redemption_grace_period %> päevane kustutusmenetlus. Menetluse käigus on domeen internetis kättesaadav. +Kuna surnud isik ei saa olla domeeni registreerijaks, algas domeeni <%= @domain.name %> suhtes <%= @delete_period_length %> päevane kustutusmenetlus. Menetluse käigus on domeen <%= @expire_warning_period %> esimest päeva internetis kättesaadav. -Domeeni suhtes õigust omaval isikul on võimalus esitada domeeni <%= @domain.name %> registripidajale <%= @registrar.name %> domeeni üleandmise taotlus, millele tuleb lisada pärimisõiguse tõend. Dokumentatsioon tuleb esitada registripidajale <%= @redemption_grace_period %> päeva jooksul. +Domeeni suhtes õigust omaval isikul on võimalus esitada domeeni <%= @domain.name %> registripidajale <%= @registrar.name %> domeeni üleandmise taotlus, millele tuleb lisada pärimisõiguse tõend. Dokumentatsioon tuleb esitada registripidajale <%= @delete_period_length %> päeva jooksul. -Kui üleandmine ei ole <%= @redemption_grace_period %> päeva jooksul toimunud, läheb domeen <%= @domain.name %> <%= @domain.force_delete_date %> domeenioksjonile .ee oksjonikeskkonda https://auction.internet.ee. Juhul kui domeenile <%= @domain.name %> ei tehta oksjonil 24h möödudes pakkumist, domeen vabaneb ja on registreerimiseks vabalt kättesaadav kõigile huvilistele. Muude võimalike oksjoni tulemuste kohta loe https://www.internet.ee/domeenid/domeenide-oksjonikeskkonna-kasutajatingimused#3-oksjonikeskkonna-enampakkumisel-osalemise-tingimused. +Kui üleandmine ei ole <%= @delete_period_length %> päeva jooksul toimunud, läheb domeen <%= @domain.name %> <%= @domain.force_delete_date %> domeenioksjonile .ee oksjonikeskkonda https://auction.internet.ee. Juhul kui domeenile <%= @domain.name %> ei tehta oksjonil 24h möödudes pakkumist, domeen vabaneb ja on registreerimiseks vabalt kättesaadav kõigile huvilistele. Muude võimalike oksjoni tulemuste kohta loe https://www.internet.ee/domeenid/domeenide-oksjonikeskkonna-kasutajatingimused#3-oksjonikeskkonna-enampakkumisel-osalemise-tingimused. Lisaküsimuste korral võtke palun ühendust oma registripidajaga: <%= render 'mailers/shared/registrar/registrar.et.text', registrar: @registrar %> @@ -19,11 +19,11 @@ Dear registrant/administrative contact of <%= @domain.name %> domain Estonian Internet Foundation (EIF) has learned that the natural person with identification code <%= @registrant.id_code %> has been deceased more than 6 months. -The registrant holding a right to the domain name <%= @domain.name %> can submit a domain name transfer application to the registrar <%= @registrar.name %>.The application must be submitted together with succession evidence certifying the acquisition of the domain. The relevant documents should be submitted to the registrar within <%= @redemption_grace_period %> days. +The registrant holding a right to the domain name <%= @domain.name %> can submit a domain name transfer application to the registrar <%= @registrar.name %>.The application must be submitted together with succession evidence certifying the acquisition of the domain. The relevant documents should be submitted to the registrar within <%= @delete_period_length %> days. -As a deceased natural person can not be the registrant of a domain, a <%= @redemption_grace_period %>-day deletion process of <%= @domain.name %> domain has started. The domain will remain available on the Internet during the deletion process. +As a deceased natural person can not be the registrant of a domain, a <%= @delete_period_length %>-day deletion process of <%= @domain.name %> domain has started. For the first <%= @expire_warning_period %> days the domain will remain available on the Internet during the deletion process. -If the transfer is not made within <%= @redemption_grace_period %> days, the domain <%= @domain.name %> will go to domain auction on <%= @domain.force_delete_date %> in the .ee auction environment at https://auction.internet.ee. If no offer is made for the domain <%= @domain.name %> at auction within 24 hours, the domain will be released and made freely available for registration to anyone interested on a first-come, first-served basis. Read more about other potential auction results at https://www.internet.ee/domains/auction-environment-user-agreement#3-terms-and-conditions-for-participation-in-the-auction-of-the-auction-environment. +If the transfer is not made within <%= @delete_period_length %> days, the domain <%= @domain.name %> will go to domain auction on <%= @domain.force_delete_date %> in the .ee auction environment at https://auction.internet.ee. If no offer is made for the domain <%= @domain.name %> at auction within 24 hours, the domain will be released and made freely available for registration to anyone interested on a first-come, first-served basis. Read more about other potential auction results at https://www.internet.ee/domains/auction-environment-user-agreement#3-terms-and-conditions-for-participation-in-the-auction-of-the-auction-environment. Should you have additional questions, please contact your registrar: <%= render 'mailers/shared/registrar/registrar.en.text', registrar: @registrar %> @@ -36,13 +36,13 @@ Should you have additional questions, please contact your registrar: Целевому учреждению Eesti Internet (EIS) стало известно, что физическое лицо с личным кодом <%= @registrant.id_code %> умерло, и с момента смерти прошло не менее 6 месяцев. -Поскольку умершее лицо не может являться регистрантом домена, начат <%= @redemption_grace_period %>-дневный процесс удаления домена <%= @domain.name %>. До завершения процесса домен доступен в Интернете. +Поскольку умершее лицо не может являться регистрантом домена, начат <%= @delete_period_length %>-дневный процесс удаления домена <%= @domain.name %>. Домен доступен в интернете на протяжении <%= @expire_warning_period %> дней после начала процесса удаления. -Лицо, обладающее правом на домен, может подать регистратору <%= @registrar.name %> домена <%= @domain.name %> ходатайство о передаче, представив справку о праве наследования. Документы должны быть представлены регистратору в течение <%= @redemption_grace_period %> дней. +Лицо, обладающее правом на домен, может подать регистратору <%= @registrar.name %> домена <%= @domain.name %> ходатайство о передаче, представив справку о праве наследования. Документы должны быть представлены регистратору в течение <%= @delete_period_length %> дней. -Если передача не состоится в течение <%= @redemption_grace_period %> дней, <%= @domain.force_delete_date %> домен <%= @domain.name %> отправится на доменный аукцион в аукционной среде .ee https://auction.internet.ee. Если в течение 24 часов в отношении домена <%= @domain.name %> не поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». О других возможных результатах аукциона читайте по ссылке https://www.internet.ee/domeny/dogovor-pol-zovatelya-aukcionnoj-sredy#3-usloviya-uchastiya-v-aukcione. +Если передача не состоится в течение <%= @delete_period_length %>дней, <%= @domain.force_delete_date %> домен <%= @domain.name %> отправится на доменный аукцион в аукционной среде .ee https://auction.internet.ee. Если в течение 24 часов в отношении домена <%= @domain.name %> не поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». О других возможных результатах аукциона читайте по ссылке https://www.internet.ee/domeny/dogovor-pol-zovatelya-aukcionnoj-sredy#3-usloviya-uchastiya-v-aukcione. В случае возникновения дополнительных вопросов свяжитесь, пожалуйста, со своим регистратором: <%= render 'mailers/shared/registrar/registrar.ru.text', registrar: @registrar %> -<%= render 'mailers/shared/signatures/signature.ru.text' %> \ No newline at end of file +<%= render 'mailers/shared/signatures/signature.ru.text' %> diff --git a/app/views/mailers/domain_expire_mailer/expired.html.erb b/app/views/mailers/domain_expire_mailer/expired.html.erb index 58043c7ce..f04301245 100644 --- a/app/views/mailers/domain_expire_mailer/expired.html.erb +++ b/app/views/mailers/domain_expire_mailer/expired.html.erb @@ -2,9 +2,11 @@

Lugupeetud .ee domeeni registreerija/halduskontakt

-

Domeeninimi <%= @domain.name %> on aegunud ja ei ole alates <%= @domain.on_hold_date %> internetis kättesaadav. Domeen <%= @domain.name %> on <%= @domain.delete_date %> domeenioksjonil .ee oksjonikeskkonnas. Juhul kui domeenile <%= @domain.name %> ei tehta oksjonil 24h möödudes pakkumist, domeen vabaneb ja on registreerimiseks vabalt kättesaadav kõigile huvilistele. Muude võimalike oksjoni tulemuste kohta loe siit.

+

Domeeninimi <%= @domain.name %> on aegunud ja ei ole alates <%= @domain.on_hold_date %> internetis kättesaadav. Registreeringu pikendamiseks pöörduge palun oma registripidaja poole.

-

Domeeni registreeringu pikendamiseks pöörduge palun oma registripidaja poole:

+

<%= @domain.name %> pikendamata jätmisel domeen kustub ja läheb <%= @domain.delete_date %> oksjonile .ee oksjonikeskkonda. Domeenioksjonite kohta loe lähemalt siit.

+ +

Domeeni <%= @domain.name %> registripidaja:

<%= render 'mailers/shared/registrar/registrar.et.html', registrar: @registrar %>

Ülevaate kõikidest endaga seotud domeenidest saate registreerija portaalist.

@@ -17,9 +19,11 @@

Dear registrant/administrative contact of .ee domain,

-

The domain name <%= @domain.name %> has expired and since <%= @domain.on_hold_date %> is no longer available on the Internet. The domain <%= @domain.name %> will be available for domain auction on <%= @domain.delete_date %> in the .ee auction portal. If no offer is made for the domain <%= @domain.name %> at auction within 24 hours, the domain will be released and made freely available for registration to anyone interested on a first-come, first-served basis. Read more about other potential auction results.

+

The domain name <%= @domain.name %> has expired and since <%= @domain.on_hold_date %> is no longer available on the Internet. To renew your domain registration, please contact your registrar.

-

To renew your domain registration, please contact your registrar:

+

If you do not renew the <%= @domain.name %> domain registration, it is deleted and put on auction to .ee domain auction environment at <%= @domain.delete_date %>. Read more about .ee domain auctions here.

+ +

Registrar of the <%= @domain.name %>:

<%= render 'mailers/shared/registrar/registrar.en.html', registrar: @registrar %>

You can find an overview of all your domains at the registrant's portal.

@@ -32,11 +36,13 @@

Уважаемый регистрант/административный контакт домена .ee

-

Срок действия доменного имени <%= @domain.name %> истек, и с <%= @domain.on_hold_date %> оно больше не доступно в интернете. <%= @domain.delete_date %> домен <%= @domain.name %> будет представлен на доменном аукционе в аукционной среде .ee. Если в течение 24 часов в отношении домена <%= @domain.name %> не поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». Читайте о других возможных результатах аукциона.

+

Срок действия доменного имени <%= @domain.name %> истек, и с <%= @domain.on_hold_date %> оно больше не доступно в интернете. Для продления регистрации домена обратитесь пожалуйста к своему регистратору.

-

Для продления регистрации домена обратитесь, пожалуйста, к своему регистратору:

+

Если доменное имя не продлено, домен <%= @domain.name %> будет удален и <%= @domain.delete_date %> идет на аукцион в .ee среду аукциона. О других возможных результатах аукциона читайте здесь.

+ +

Pегистратор домена <%= @domain.name %>:

<%= render 'mailers/shared/registrar/registrar.ru.html', registrar: @registrar %>

Обзор всех связанных с вами доменов можете получить на портале регистратора.

-<%= render 'mailers/shared/signatures/signature.ru.html' %> \ No newline at end of file +<%= render 'mailers/shared/signatures/signature.ru.html' %> diff --git a/app/views/mailers/domain_expire_mailer/expired.text.erb b/app/views/mailers/domain_expire_mailer/expired.text.erb index 7bd0ffde6..634746493 100644 --- a/app/views/mailers/domain_expire_mailer/expired.text.erb +++ b/app/views/mailers/domain_expire_mailer/expired.text.erb @@ -2,9 +2,11 @@ Domeen <%= @domain.name %> on aegunud Lugupeetud .ee domeeni registreerija/halduskontakt -Domeeninimi <%= @domain.name %> on aegunud ja ei ole alates <%= @domain.on_hold_date %> internetis kättesaadav. Domeen <%= @domain.name %> on <%= @domain.delete_date %> domeenioksjonil .ee https://oksjon.internet.ee. Juhul kui domeenile <%= @domain.name %> ei tehta oksjonil 24h möödudes pakkumist, domeen vabaneb ja on registreerimiseks vabalt kättesaadav kõigile huvilistele. Muude võimalike oksjoni tulemuste kohta loe siit https://www.internet.ee/domeenid/domeenide-oksjonikeskkonna-kasutajatingimused#3-oksjonikeskkonna-enampakkumisel-osalemise-tingimused. +Domeeninimi <%= @domain.name %> on aegunud ja ei ole alates <%= @domain.on_hold_date %> internetis kättesaadav. Registreeringu pikendamiseks pöörduge palun oma registripidaja poole. -Domeeni registreeringu pikendamiseks pöörduge palun oma registripidaja poole: +<%= @domain.name %> pikendamata jätmisel domeen kustub ja läheb <%= @domain.delete_date %> oksjonile .ee oksjonikeskkonda. Domeenioksjonite kohta loe lähemalt siit https://www.internet.ee/domeenid/domeenide-oksjonikeskkonna-kasutajatingimused#3-oksjonikeskkonna-enampakkumisel-osalemise-tingimused. + +Domeeni <%= @domain.name %> registripidaja: <%= render 'mailers/shared/registrar/registrar.et.text', registrar: @registrar %> Ülevaate kõikidest endaga seotud domeenidest saate registreerija portaalist https://registrant.internet.ee/registrant/. @@ -17,9 +19,11 @@ Domain <%= @domain.name %> has expired Dear registrant/administrative contact of .ee domain, -The domain name <%= @domain.name %> has expired and since <%= @domain.on_hold_date %> is no longer available on the Internet. The domain <%= @domain.name %> will be available for domain auction on <%= @domain.delete_date %> in the .ee auction portal at https://auction.internet.ee. If no offer is made for the domain <%= @domain.name %> at auction within 24 hours, the domain will be released and made freely available for registration to anyone interested on a first-come, first-served basis. Read more about other potential auction results at https://www.internet.ee/domains/auction-environment-user-agreement#3-terms-and-conditions-for-participation-in-the-auction-of-the-auction-environment. +The domain name <%= @domain.name %> has expired and since <%= @domain.on_hold_date %> is no longer available on the Internet. To renew your domain registration, please contact your registrar. -To renew your domain registration, please contact your registrar: +If you do not renew the <%= @domain.name %> domain registration, it is deleted and put on auction to .ee domain auction environment at <%= @domain.delete_date %>. Read more about other potential auction results at https://www.internet.ee/domains/auction-environment-user-agreement#3-terms-and-conditions-for-participation-in-the-auction-of-the-auction-environment. + +Registrar of the <%= @domain.name %>: <%= render 'mailers/shared/registrar/registrar.en.text', registrar: @registrar %> You can find an overview of all your domains at the registrant's portal https://registrant.internet.ee/registrant/. @@ -32,11 +36,13 @@ You can find an overview of all your domains at the registrant's portal https:// Уважаемый регистрант/административный контакт домена .ee -Срок действия доменного имени <%= @domain.name %> истек, и с <%= @domain.on_hold_date %> оно больше не доступно в интернете. <%= @domain.delete_date %> домен <%= @domain.name %> будет представлен на доменном аукционе в аукционной среде .ee https://oksjon.internet.ee. Если в течение 24 часов в отношении домена <%= @domain.name %> не поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». О других возможных результатах аукциона читайте по ссылке https://www.internet.ee/domeny/dogovor-pol-zovatelya-aukcionnoj-sredy#3-usloviya-uchastiya-v-aukcione. +Срок действия доменного имени <%= @domain.name %> истек, и с <%= @domain.on_hold_date %> оно больше не доступно в интернете. Для продления регистрации домена обратитесь пожалуйста к своему регистратору. -Для продления регистрации домена обратитесь, пожалуйста, к своему регистратору: +Если доменное имя не продлено, домен <%= @domain.name %> будет удален и <%= @domain.delete_date %> идет на аукцион в .ee среду аукциона. О других возможных результатах аукциона читайте здесь https://www.internet.ee/domeny/dogovor-pol-zovatelya-aukcionnoj-sredy#3-usloviya-uchastiya-v-aukcione. + +Pегистратор домена <%= @domain.name %>: <%= render 'mailers/shared/registrar/registrar.ru.text', registrar: @registrar %> Обзор всех связанных с вами доменов можете получить на портале регистратора https://registrant.internet.ee/registrant/ -<%= render 'mailers/shared/signatures/signature.ru.text' %> \ No newline at end of file +<%= render 'mailers/shared/signatures/signature.ru.text' %> diff --git a/app/views/registrant/contacts/show/_domains.html.erb b/app/views/registrant/contacts/show/_domains.html.erb index bb6d39fc0..d783b55b2 100644 --- a/app/views/registrant/contacts/show/_domains.html.erb +++ b/app/views/registrant/contacts/show/_domains.html.erb @@ -1,4 +1,5 @@ -<% domains = contact.all_domains(page: params[:domain_page], per: 20, params: params) %> +<% domains = contact.all_domains(page: params[:domain_page], per: 20, + params: domain_filter_params.to_h, requester: @requester_contact) %>
@@ -50,4 +51,4 @@ -
\ No newline at end of file +
diff --git a/app/views/registrant/domains/download_list.haml b/app/views/registrant/domains/download_list.haml deleted file mode 100644 index f0af344cd..000000000 --- a/app/views/registrant/domains/download_list.haml +++ /dev/null @@ -1,28 +0,0 @@ -!!! -%html - %head - %meta{:content => "text/html; charset=utf-8", "http-equiv" => "Content-Type"} - %title Contacts - %body - .col-md-12 - .table-responsive - %table.table.table-hover.table-bordered.table-condensed - %thead - %tr - %th{class: 'col-xs-2'} - =t(:name) - %th{class: 'col-xs-2'} - =t('.registrant') - %th{class: 'col-xs-2'} - =t(:valid_to) - %th{class: 'col-xs-2'} - =t(:registrar_name) - %tbody - - @domains.result.each do |x| - %tr - %td= x.name - %td= x.registrant - %td= l(x.valid_to, format: :short) - %td= x.registrar - .row - .col-md-6 diff --git a/app/views/registrant/domains/index.html.erb b/app/views/registrant/domains/index.html.erb index acb9afcff..1254bfbc8 100644 --- a/app/views/registrant/domains/index.html.erb +++ b/app/views/registrant/domains/index.html.erb @@ -18,6 +18,13 @@ <%= f.search_field :registrant_ident_eq, class: 'form-control', placeholder: t(:registrant_ident) %> + +
+
+ <%= label_tag t(:results_per_page) %> + <%= text_field_tag :results_per_page, params[:results_per_page], class: 'form-control', placeholder: t(:results_per_page) %> +
+
@@ -32,43 +39,27 @@ <%= f.search_field :valid_to_lteq, value: params[:q][:valid_to_lteq], class: 'form-control js-datepicker', placeholder: t(:valid_to_until) %>
-
-
- <%= label_tag t(:results_per_page) %> - <%= text_field_tag :results_per_page, params[:results_per_page], class: 'form-control', placeholder: t(:results_per_page) %> -
-
+ -
- - <%= link_to(t('.reset_btn'), registrant_domains_path, class: 'btn btn-default') %> + <%= button_tag t('.download_pdf_btn'), + formaction: registrant_domains_path(format: :pdf), + name: nil, + class: 'btn btn-default' %> + <%= button_tag t('.download_csv_btn'), + formaction: registrant_domains_path(format: :csv), + name: nil, + class: 'btn btn-default' %> + <%= link_to t('.reset_btn'), registrant_domains_path, + class: 'btn btn-default' %>
-
-
-
- - -
-
-
-
-
-
<% end %> diff --git a/app/views/registrant/domains/list_pdf.html.erb b/app/views/registrant/domains/list_pdf.html.erb new file mode 100644 index 000000000..4ce4f5ed0 --- /dev/null +++ b/app/views/registrant/domains/list_pdf.html.erb @@ -0,0 +1,32 @@ + + + +
+
+
+ + + + + + + + + + + + <% @domains.each do |domain| %> + + + + + + + <% end %> + +
<%= Domain.human_attribute_name :name %><%= Registrant.model_name.human %><%= Domain.human_attribute_name :valid_to %><%= Registrar.model_name.human %>
<%= domain.name %><%= domain.registrant %><%= l(domain.valid_to, format: :short) %><%= domain.registrar %>
+
+
+
+ + diff --git a/app/views/registrant/domains/partials/_dnskeys.haml b/app/views/registrant/domains/partials/_dnskeys.haml index 6d5759e65..ddd95e952 100644 --- a/app/views/registrant/domains/partials/_dnskeys.haml +++ b/app/views/registrant/domains/partials/_dnskeys.haml @@ -1,5 +1,4 @@ -- panel_class = @domain.errors.messages[:dnskeys] ? 'panel-danger' : 'panel-default' -#dnskeys.panel{class: panel_class} +.panel.panel-default .panel-heading.clearfix = t(:dnskeys) .table-responsive @@ -17,9 +16,3 @@ %td= x.protocol %td= x.alg %td= x.public_key - - if @domain.errors.messages[:dnskeys] - %tfoot - - @domain.errors.messages[:dnskeys].each do |x| - %tr - %td{colspan: 4}= x - diff --git a/app/views/registrant/domains/partials/_keyrelays.haml b/app/views/registrant/domains/partials/_keyrelays.haml deleted file mode 100644 index d2d39f6ba..000000000 --- a/app/views/registrant/domains/partials/_keyrelays.haml +++ /dev/null @@ -1,20 +0,0 @@ -.panel{class: 'panel-default'} - .panel-heading.clearfix - = t(:keyrelays) - .table-responsive - %table.table.table-hover.table-bordered.table-condensed - %thead - %tr - %th{class: 'col-xs-4'}= t(:uploaded_at) - %th{class: 'col-xs-3'}= t(:expiry) - %th{class: 'col-xs-2'}= t(:requester) - %th{class: 'col-xs-2'}= t(:accepter) - %th{class: 'col-xs-1'}= t(:status) - %tbody - - @domain.keyrelays.includes([:requester, :accepter]).order(pa_date: :desc).each do |x| - %tr - %td= link_to(x.pa_date, [:registrar, x]) - %td= x.expiry - %td= link_to(x.requester, [:registrar, x.requester]) - %td= link_to(x.accepter, [:registrar, x.accepter]) - %td= x.status diff --git a/app/views/registrant/domains/partials/_nameservers.haml b/app/views/registrant/domains/partials/_nameservers.haml index db3ca759a..0bc22732d 100644 --- a/app/views/registrant/domains/partials/_nameservers.haml +++ b/app/views/registrant/domains/partials/_nameservers.haml @@ -1,5 +1,4 @@ -- panel_class = @domain.errors.messages[:nameservers] ? 'panel-danger' : 'panel-default' -#nameservers.panel{class: panel_class} +.panel.panel-default .panel-heading.clearfix = t(:nameservers) .table-responsive @@ -15,9 +14,3 @@ %td= x %td= x.ipv4 %td= x.ipv6 - - if @domain.errors.messages[:nameservers] - %tfoot - - @domain.errors.messages[:nameservers].each do |x| - %tr - %td{colspan: 3}= x - diff --git a/app/views/registrant/domains/show.html.erb b/app/views/registrant/domains/show.html.erb index d09253b6b..81ca04b51 100644 --- a/app/views/registrant/domains/show.html.erb +++ b/app/views/registrant/domains/show.html.erb @@ -50,9 +50,3 @@ <%= render 'registrant/domains/partials/dnskeys' %> - -
-
- <%= render 'registrant/domains/partials/keyrelays' %> -
-
diff --git a/app/views/registrar/account_activities/_search_form.html.erb b/app/views/registrar/account_activities/_search_form.html.erb new file mode 100644 index 000000000..92a715096 --- /dev/null +++ b/app/views/registrar/account_activities/_search_form.html.erb @@ -0,0 +1,49 @@ +
+
+ <%= search_form_for @q, url: [:registrar, :account_activities], html: { style: 'margin-bottom: 0;' } do |f| %> +
+
+
+ <%= f.label t(:activity_type) %> + <%= f.select :activity_type_in, AccountActivity.types_for_select, {}, class: 'form-control js-combobox', placeholder: t(:choose), multiple: true %> +
+
+ +
+
+ <%= f.label t(:description) %> + <%= f.search_field :description_cont, class: 'form-control', placeholder: t(:description), autocomplete: 'off' %> +
+
+
+ +
+
+
+ <%= f.label t(:receipt_date_from) %> + <%= f.search_field :created_at_gteq, value: params[:q][:created_at_gteq], class: 'form-control js-datepicker', placeholder: t(:receipt_date_from) %> +
+
+ +
+
+ <%= f.label t(:receipt_date_until) %> + <%= f.search_field :created_at_lteq, value: params[:q][:created_at_lteq], class: 'form-control js-datepicker', placeholder: t(:receipt_date_until) %> +
+
+ +
+ + <%= button_tag t('.download_btn'), + formaction: registrar_account_activities_path(format: 'csv'), + class: 'btn btn-default' %> + <%= link_to(t('.reset_btn'), registrar_account_activities_path, class: 'btn btn-default') %> +
+
+ <% end %> +
+
diff --git a/app/views/registrar/account_activities/index.haml b/app/views/registrar/account_activities/index.haml deleted file mode 100644 index 3cc6b34e4..000000000 --- a/app/views/registrar/account_activities/index.haml +++ /dev/null @@ -1,61 +0,0 @@ -- content_for :actions do - = link_to(t(:back_to_billing), registrar_invoices_path, class: 'btn btn-default') - = link_to(t(:export_csv), url_for(params.merge(format: 'csv')), class: 'btn btn-default') - -= render 'shared/title', name: t(:account_activity) - -.row - .col-md-12 - = search_form_for @q, url: [:registrar, :account_activities], html: { style: 'margin-bottom: 0;' } do |f| - .row - .col-md-6 - .form-group - = f.label t(:activity_type) - = f.select :activity_type_in, AccountActivity.types_for_select, {}, class: 'form-control js-combobox', placeholder: t(:choose), multiple: true - .col-md-6 - .form-group - = f.label t(:description) - = f.search_field :description_cont, class: 'form-control', placeholder: t(:description), autocomplete: 'off' - .row - .col-md-3 - .form-group - = f.label t(:receipt_date_from) - = f.search_field :created_at_gteq, value: params[:q][:created_at_gteq], class: 'form-control js-datepicker', placeholder: t(:receipt_date_from) - .col-md-3 - .form-group - = f.label t(:receipt_date_until) - = f.search_field :created_at_lteq, value: params[:q][:created_at_lteq], class: 'form-control js-datepicker', placeholder: t(:receipt_date_until) - .col-md-6{style: 'padding-top: 25px;'} - %button.btn.btn-default -   - %span.glyphicon.glyphicon-search -   - = link_to(t('.reset_btn'), registrar_account_activities_path, class: 'btn btn-default') -%hr - -.row - .col-md-12 - .table-responsive - %table.table.table-hover.table-condensed - %thead - %tr - %th{class: 'col-xs-5'} - = sort_link(@q, 'description') - %th{class: 'col-xs-2'} - = sort_link(@q, 'activity_type') - %th{class: 'col-xs-3'} - = sort_link(@q, 'created_at', AccountActivity.human_attribute_name(:created_at)) - %th{class: 'col-xs-2'} - = sort_link(@q, 'sum') - %tbody - - @account_activities.each do |x| - %tr - %td= x.description.present? ? x.description : '-' - %td= x.activity_type ? t(x.activity_type) : '' - %td= l(x.created_at) - - c = x.sum > 0.0 ? 'text-success' : 'text-danger' - - s = x.sum > 0.0 ? "+#{x.sum} #{x.currency}" : "#{x.sum} #{x.currency}" - %td{class: c}= s -.row - .col-md-12 - = paginate @account_activities diff --git a/app/views/registrar/account_activities/index.html.erb b/app/views/registrar/account_activities/index.html.erb new file mode 100644 index 000000000..c5eaf2063 --- /dev/null +++ b/app/views/registrar/account_activities/index.html.erb @@ -0,0 +1,60 @@ +<% content_for :actions do %> + <%= link_to(t(:back_to_billing), registrar_invoices_path, class: 'btn btn-default') %> +<% end %> + +<%= render 'shared/title', name: t(:account_activity) %> + +<%= render 'search_form' %> + +
+ +
+
+
+ + + + + + + + + + + <% @account_activities.each do |x| %> + + + + + <% c = x.sum > 0.0 ? 'text-success' : 'text-danger' %> + <% s = x.sum > 0.0 ? "+#{x.sum} #{x.currency}" : "#{x.sum} #{x.currency}" %> + + + <% end %> + +
+ <%= sort_link(@q, 'description') %> + + <%= sort_link(@q, 'activity_type') %> + + <%= sort_link(@q, 'created_at', AccountActivity.human_attribute_name(:created_at)) %> + + <%= sort_link(@q, 'sum') %> +
+ <%= x.description.present? ? x.description : '-' %> + + <%= x.activity_type ? t(x.activity_type) : '' %> + + <%= l(x.created_at) %> + + <%= s %> +
+
+
+
+ +
+
+ <%= paginate @account_activities %> +
+
diff --git a/app/views/registrar/base/_navbar.haml b/app/views/registrar/base/_navbar.haml index d94097bd3..4361e8b31 100644 --- a/app/views/registrar/base/_navbar.haml +++ b/app/views/registrar/base/_navbar.haml @@ -1,7 +1,7 @@ .navbar-collapse.collapse %ul.nav.navbar-nav - if can? :view, Depp::Domain - - active_class = %w(registrar/domains registrar/check registrar/renew registrar/tranfer registrar/keyrelays).include?(params[:controller]) ? 'active' :nil + - active_class = %w(registrar/domains registrar/check registrar/renew registrar/tranfer).include?(params[:controller]) ? 'active' :nil %li{class: active_class}= link_to t(:domains), registrar_domains_path - if can? :view, Depp::Contact diff --git a/app/views/registrar/contacts/_search_form.html.erb b/app/views/registrar/contacts/_search_form.html.erb new file mode 100644 index 000000000..e15ff1880 --- /dev/null +++ b/app/views/registrar/contacts/_search_form.html.erb @@ -0,0 +1,117 @@ +<%= search_form_for [:registrar, @q], html: { style: 'margin-bottom: 0;', class: 'js-form', autocomplete: 'off' } do |f| %> +
+
+
+ <%= f.label :name %> + <%= f.search_field :name_matches, value: params[:q][:name_matches], class: 'form-control', placeholder: t(:name) %> +
+
+ +
+
+ <%= f.label t(:id) %> + <%= f.search_field :code_eq, class: 'form-control', placeholder: t(:id) %> +
+
+ +
+
+ <%= f.label t(:ident) %> + <%= f.search_field :ident_matches, class: 'form-control', placeholder: t(:ident) %> +
+
+ +
+
+ <%= label_tag t(:ident_type) %> + <%= select_tag '[q][ident_type_eq]', options_for_select(ident_types, params[:q][:ident_type_eq]), { include_blank: true, placeholder: t(:choose), class: 'form-control selectize' } %> +
+
+
+ +
+
+
+ <%= f.label t(:email) %> + <%= f.search_field :email_matches, class: 'form-control', placeholder: t(:email) %> +
+
+ +
+
+ <%= label_tag t(:country) %> + <%= select_tag '[q][country_code_eq]', SortedCountry.all_options(params[:q][:country_code_eq]), { include_blank: true, placeholder: t(:choose), class: 'form-control selectize' } %> +
+
+ +
+
+ <%= label_tag t(:contact_type) %> + <%= select_tag '[q][domain_contacts_type_in]', options_for_select([['admin', 'AdminDomainContact'], ['tech', 'TechDomainContact'], ['registrant', 'registrant']], params[:q][:domain_contacts_type_in]), { multiple: true, placeholder: t(:choose), class: 'form-control js-combobox' } %> +
+
+
+ +
+
+
+ <%= f.label t(:registrar_name) %> + <%= f.select :registrar_id_eq, Registrar.all.map { |x| [x, x.id] }, { include_blank: true }, class: 'form-control selectize', placeholder: t(:choose) %> +
+
+ +
+
+ <%= f.label t(:created_at_from) %> + <%= f.search_field :created_at_gteq, value: params[:q][:created_at_gteq], class: 'form-control js-datepicker', placeholder: t(:created_at_from) %> +
+
+ +
+
+ <%= f.label t(:created_at_until) %> + <%= f.search_field :created_at_lteq, value: params[:q][:created_at_lteq], class: 'form-control js-datepicker', placeholder: t(:created_at_until) %> +
+
+ +
+
+ <%= f.label t(:updated_at) %> + <%= f.search_field :updated_at_gteq, value: params[:q][:updated_at_gteq], class: 'form-control js-datepicker', placeholder: t(:updated_at) %> +
+
+
+ +
+
+
+ <%= label_tag t(:status) %> + <%= select_tag :statuses_contains, options_for_select(Contact::STATUSES, params[:statuses_contains]), { multiple: true, placeholder: t(:choose), class: 'form-control js-combobox' } %> +
+
+ +
+
+ <%= label_tag t(:results_per_page) %> + <%= text_field_tag :results_per_page, params[:results_per_page], class: 'form-control', placeholder: t(:results_per_page) %> +
+
+ +
+ + <%= button_tag t('.download_pdf_btn'), + formaction: registrar_contacts_path(format: :pdf), + name: nil, + class: 'btn btn-default' %> + <%= button_tag t('.download_csv_btn'), + formaction: registrar_contacts_path(format: :csv), + name: nil, + class: 'btn btn-default' %> + <%= link_to(t('.reset_btn'), registrar_contacts_path, class: 'btn btn-default') %> +
+
+<% end %> diff --git a/app/views/registrar/contacts/download_list.haml b/app/views/registrar/contacts/download_list.haml deleted file mode 100644 index 51423a3f2..000000000 --- a/app/views/registrar/contacts/download_list.haml +++ /dev/null @@ -1,30 +0,0 @@ -!!! -%html - %head - %meta{:content => "text/html; charset=utf-8", "http-equiv" => "Content-Type"} - %title Contacts - %body - .row - .col-md-12 - .table-responsive - %table.table.table-hover.table-bordered.table-condensed - %thead - %tr - %th{class: 'col-xs-2'} - =t(:name) - %th{class: 'col-xs-2'} - =t(:id) - %th{class: 'col-xs-2'} - =t(:ident) - %th{class: 'col-xs-2'} - =t(:created_at) - %th{class: 'col-xs-2'} - =t(:registrar_name) - %tbody - - @contacts.each do |contact| - %tr - %td= contact - %td= contact.code - %td= ident_for(contact) - %td= l(contact.created_at, format: :short) - %td= contact.registrar diff --git a/app/views/registrar/contacts/index.haml b/app/views/registrar/contacts/index.haml deleted file mode 100644 index 518e6eccf..000000000 --- a/app/views/registrar/contacts/index.haml +++ /dev/null @@ -1,120 +0,0 @@ -- content_for :actions do - = link_to(t(:new), new_registrar_contact_path, class: 'btn btn-primary') -= render 'shared/title', name: t(:contacts) - -.row - .col-md-12 - = search_form_for [:registrar, @q], html: { style: 'margin-bottom: 0;', class: 'js-form', autocomplete: 'off' } do |f| - .row - .col-md-3 - .form-group - = f.label :name - = f.search_field :name_matches, value: params[:q][:name_matches], class: 'form-control', placeholder: t(:name) - .col-md-3 - .form-group - = f.label t(:id) - = f.search_field :code_eq, class: 'form-control', placeholder: t(:id) - .col-md-3 - .form-group - = f.label t(:ident) - = f.search_field :ident_matches, class: 'form-control', placeholder: t(:ident) - .col-md-3 - .form-group - = label_tag t(:ident_type) - = select_tag '[q][ident_type_eq]', options_for_select(ident_types, params[:q][:ident_type_eq]), { include_blank: true, placeholder: t(:choose), class: 'form-control selectize' } - .row - .col-md-3 - .form-group - = f.label t(:email) - = f.search_field :email_matches, class: 'form-control', placeholder: t(:email) - .col-md-3 - .form-group - = label_tag t(:country) - = select_tag '[q][country_code_eq]', SortedCountry.all_options(params[:q][:country_code_eq]), { include_blank: true, placeholder: t(:choose), class: 'form-control selectize' } - .col-md-6 - .form-group - = label_tag t(:contact_type) - = select_tag '[q][domain_contacts_type_in]', options_for_select([['admin', 'AdminDomainContact'], ['tech', 'TechDomainContact'], ['registrant', 'registrant']], params[:q][:domain_contacts_type_in]), { multiple: true, placeholder: t(:choose), class: 'form-control js-combobox' } - .row - .col-md-3 - .form-group - = f.label t(:registrar_name) - = f.select :registrar_id_eq, Registrar.all.map { |x| [x, x.id] }, { include_blank: true }, class: 'form-control selectize', placeholder: t(:choose) - .col-md-3 - .form-group - = f.label t(:created_at_from) - = f.search_field :created_at_gteq, value: params[:q][:created_at_gteq], class: 'form-control js-datepicker', placeholder: t(:created_at_from) - .col-md-3 - .form-group - = f.label t(:created_at_until) - = f.search_field :created_at_lteq, value: params[:q][:created_at_lteq], class: 'form-control js-datepicker', placeholder: t(:created_at_until) - .col-md-3 - .form-group - = f.label t(:updated_at) - = f.search_field :updated_at_gteq, value: params[:q][:updated_at_gteq], class: 'form-control js-datepicker', placeholder: t(:updated_at) - .row - .col-md-6 - .form-group - = label_tag t(:status) - = select_tag :statuses_contains, options_for_select(Contact::STATUSES, params[:statuses_contains]), { multiple: true, placeholder: t(:choose), class: 'form-control js-combobox' } - .col-md-3 - .form-group - = label_tag t(:results_per_page) - = text_field_tag :results_per_page, params[:results_per_page], class: 'form-control', placeholder: t(:results_per_page) - .col-md-3{style: 'padding-top: 25px;'} - %button.btn.btn-primary -   - %span.glyphicon.glyphicon-search -   - = link_to(t('.reset_btn'), registrar_contacts_path, class: 'btn btn-default') - .row - .col-md-3 - .btn-group{:role => "group"} - %button.btn.btn-default.dropdown-toggle{"aria-expanded" => "false", "aria-haspopup" => "true", "data-toggle" => "dropdown", :type => "button"} - Download - %span.caret - %ul.dropdown-menu - %li= link_to 'PDF', download_list_registrar_contacts_path(q: params[:q], format: "pdf") - %li= link_to 'CSV', download_list_registrar_contacts_path(q: params[:q], format: "csv") - .col-md-3 - .col-md-3 - .col-md-3 - -%hr -.row - .col-md-12 - .table-responsive - %table.table.table-hover.table-bordered.table-condensed.contacts - %thead - %tr - %th{class: 'col-xs-2'} - = sort_link(@q, 'name', t(:name)) - %th{class: 'col-xs-2'} - = sort_link(@q, 'code', t(:id)) - %th{class: 'col-xs-2'} - = sort_link(@q, 'ident', t(:ident)) - %th{class: 'col-xs-2'} - = sort_link(@q, 'email', t(:created_at)) - %th{class: 'col-xs-2'} - = sort_link(@q, 'registrar_name', t(:registrar_name)) - %th{class: 'col-xs-2'}= t(:actions) - %tbody - - @contacts.each do |contact| - %tr - %td= link_to(contact.name, registrar_contact_path(id: contact.code)) - %td= contact.code - %td= ident_for(contact) - %td= l(contact.created_at, format: :short) - %td - - if contact.registrar - = contact.registrar - %td - = link_to(t(:edit), edit_registrar_contact_path(contact.code), class: 'btn btn-primary btn-xs') - = link_to(t(:delete), delete_registrar_contact_path(contact.code), class: 'btn btn-default btn-xs') - -.row - .col-md-6 - = paginate @contacts - .col-md-6.text-right - .pagination - = t(:result_count, count: @contacts.total_count) diff --git a/app/views/registrar/contacts/index.html.erb b/app/views/registrar/contacts/index.html.erb new file mode 100644 index 000000000..4a7e8759a --- /dev/null +++ b/app/views/registrar/contacts/index.html.erb @@ -0,0 +1,77 @@ +<% content_for :actions do %> + <%= link_to(t(:new), new_registrar_contact_path, class: 'btn btn-primary') %> +<% end %> +<%= render 'shared/title', name: t(:contacts) %> +
+
+ <%= render 'search_form' %> +
+
+
+
+
+
+ + + + + + + + + + + + + <% @contacts.each do |contact| %> + + + + + + + + + <% end %> + +
+ <%= sort_link(@q, 'name', t(:name)) %> + + <%= sort_link(@q, 'code', t(:id)) %> + + <%= sort_link(@q, 'ident', t(:ident)) %> + + <%= sort_link(@q, 'email', t(:created_at)) %> + + <%= sort_link(@q, 'registrar_name', t(:registrar_name)) %> + + <%= t(:actions) %> +
+ <%= link_to(contact.name, registrar_contact_path(id: contact.code)) %> + + <%= contact.code %> + + <%= ident_for(contact) %> + + <%= l(contact.created_at, format: :short) %> + + <% if contact.registrar %> + <%= contact.registrar %> + <% end %> + + <%= link_to(t(:edit), edit_registrar_contact_path(contact.code), class: 'btn btn-primary btn-xs') %> + <%= link_to(t(:delete), delete_registrar_contact_path(contact.code), class: 'btn btn-default btn-xs') %> +
+
+
+
+
+
+ <%= paginate @contacts %> +
+
+ +
+
diff --git a/app/views/registrar/contacts/list_pdf.html.erb b/app/views/registrar/contacts/list_pdf.html.erb new file mode 100644 index 000000000..b9bbb1c0e --- /dev/null +++ b/app/views/registrar/contacts/list_pdf.html.erb @@ -0,0 +1,34 @@ + + + +
+
+
+ + + + + + + + + + + + + <% @contacts.each do |contact| %> + + + + + + + + <% end %> + +
<%= Contact.human_attribute_name :name %><%= Contact.human_attribute_name :code %><%= Contact.human_attribute_name :ident %><%= Contact.human_attribute_name :created_at %><%= Registrar.model_name.human %>
<%= contact %><%= contact.code %><%= ident_for(contact) %><%= l(contact.created_at, format: :short) %><%= contact.registrar %>
+
+
+
+ + diff --git a/app/views/registrar/contacts/partials/_domains.haml b/app/views/registrar/contacts/partials/_domains.haml index d2943e8ef..cf721cb86 100644 --- a/app/views/registrar/contacts/partials/_domains.haml +++ b/app/views/registrar/contacts/partials/_domains.haml @@ -1,5 +1,6 @@ -- domains = contact.all_domains(page: params[:domain_page], per: 20, params: params) -#contacts.panel.panel-default +- domains = contact.all_domains(page: params[:domain_page], per: 20, + params: domain_filter_params.to_h) +.panel.panel-default .panel-heading .pull-left = t(:domains) diff --git a/app/views/registrar/domains/_form.haml b/app/views/registrar/domains/_form.haml index d6428233b..690d0ee06 100644 --- a/app/views/registrar/domains/_form.haml +++ b/app/views/registrar/domains/_form.haml @@ -1,4 +1,5 @@ - path = (params[:domain_name]) ? update_registrar_domains_path : registrar_domains_path +- legaldoc_mandatory = params[:domain_name].blank? && current_registrar_user.legaldoc_mandatory? = form_tag(path, class: 'form-horizontal', multipart: true) do .row .col-md-8 @@ -14,7 +15,7 @@ .panel-body .form-group .col-md-3.control-label - - c, fr = 'required', true if params[:domain_name].blank? + - c, fr = 'required', true if legaldoc_mandatory = label_tag 'domain[legal_document]', t(:legal_document), class: c %p.help-block= t(:legal_document_max_size) .col-md-7 diff --git a/app/views/registrar/domains/_search_form.html.erb b/app/views/registrar/domains/_search_form.html.erb index b494e0d8d..08b370b76 100644 --- a/app/views/registrar/domains/_search_form.html.erb +++ b/app/views/registrar/domains/_search_form.html.erb @@ -3,7 +3,7 @@
<%= f.label :name, for: nil %> - <%= f.search_field :name_matches, value: params[:q][:name_matches], class: 'form-control', + <%= f.search_field :name_matches, value: search_params[:name_matches], class: 'form-control', placeholder: t(:name) %>
@@ -44,7 +44,7 @@
<%= f.label :valid_to_from, for: nil %> - <%= f.search_field :valid_to_gteq, value: params[:q][:valid_to_gteq], + <%= f.search_field :valid_to_gteq, value: search_params[:valid_to_gteq], class: 'form-control js-datepicker', placeholder: t(:valid_to_from) %>
@@ -53,7 +53,7 @@
<%= f.label :valid_to_until, for: nil %> - <%= f.search_field :valid_to_lteq, value: params[:q][:valid_to_lteq], + <%= f.search_field :valid_to_lteq, value: search_params[:valid_to_lteq], class: 'form-control js-datepicker', placeholder: t(:valid_to_until) %>
@@ -74,14 +74,14 @@
-
+
- <%= button_tag t('.download_btn'), class: 'btn btn-primary export-domains-csv-btn', - formaction: registrar_domains_path(format: 'csv') %> + <%= button_tag t('.download_btn'), formaction: registrar_domains_path(format: 'csv'), + class: 'btn btn-default' %> <%= link_to t('.reset_btn'), registrar_domains_path, class: 'btn btn-default' %>
diff --git a/app/views/registrar/domains/delete.haml b/app/views/registrar/domains/delete.haml index ab1bdfa31..bea9ed118 100644 --- a/app/views/registrar/domains/delete.haml +++ b/app/views/registrar/domains/delete.haml @@ -10,14 +10,14 @@ .col-md-4.control-label = label_tag 'domain[verified]', t(:verified) .col-md-6 - = check_box_tag 'domain[verified]', '1', params[:verified].eql?('1'), onclick: "return (confirm('#{t(:verified_confirm)}') ? true : false);" + = check_box_tag 'domain[verified]', '1', params[:verified].eql?('1'), onclick: ("return (confirm('#{t(:verified_confirm)}') ? true : false);" if current_registrar_user.legaldoc_mandatory?) .form-group .col-md-4.control-label - = label_tag 'domain[legal_document]', t(:legal_document), class: 'required' + = label_tag 'domain[legal_document]', t(:legal_document) %p.help-block= t(:legal_document_max_size) .col-md-6 - = file_field_tag 'domain[legal_document]', required: true + = file_field_tag 'domain[legal_document]' = hidden_field_tag 'domain[name]', params[:domain_name] %hr .row diff --git a/app/views/registrar/domains/form/_general.haml b/app/views/registrar/domains/form/_general.haml index 0a729a262..5fa4d2a89 100644 --- a/app/views/registrar/domains/form/_general.haml +++ b/app/views/registrar/domains/form/_general.haml @@ -31,7 +31,7 @@ .col-md-7 = check_box_tag 'domain[verified]', '1', @domain_params[:verified].eql?('1'), onclick: "return (confirm('#{t(:verified_confirm)}') ? true : false);" - - unless params[:domain_name] + - if !params[:domain_name] || @dispute.present? .form-group .col-md-3.control-label = label_tag :domain_reserved_pw, t(:reserved_pw) diff --git a/app/views/registrar/domains/info.html.erb b/app/views/registrar/domains/info.html.erb index 1fcfc23c3..e88882233 100644 --- a/app/views/registrar/domains/info.html.erb +++ b/app/views/registrar/domains/info.html.erb @@ -6,6 +6,10 @@ class: 'btn btn-default') %> <%= link_to(t(:delete), delete_registrar_domains_path(domain_name: params[:domain_name]), class: 'btn btn-default') %> + <% if @client_holded %> + <%= link_to(t(:remove_client_hold), remove_hold_registrar_domains_path(domain_name: params[:domain_name]), + class: 'btn btn-default') %> + <% end %> <% else %> <%= link_to t('.transfer_btn'), new_registrar_domain_transfer_path(domain_name: params[:domain_name]), class: 'btn btn-default' %> diff --git a/app/views/registrar/domains/partials/_contacts.haml b/app/views/registrar/domains/partials/_contacts.haml index b94f99ee2..48d1ac21f 100644 --- a/app/views/registrar/domains/partials/_contacts.haml +++ b/app/views/registrar/domains/partials/_contacts.haml @@ -1,4 +1,4 @@ -#tech_contacts.panel.panel-default +.panel.panel-default .panel-heading.clearfix %h3.panel-title= t(:contacts) .table-responsive @@ -14,4 +14,4 @@ %tr %td= x['type'] %td= registrant.name - %td= x.text \ No newline at end of file + %td= x.text diff --git a/app/views/registrar/domains/partials/_nameservers.haml b/app/views/registrar/domains/partials/_nameservers.haml index 66ef010e6..69f147bc4 100644 --- a/app/views/registrar/domains/partials/_nameservers.haml +++ b/app/views/registrar/domains/partials/_nameservers.haml @@ -1,4 +1,4 @@ -#nameservers.panel.panel-default +.panel.panel-default .panel-heading.clearfix %h3.panel-title= t(:nameservers) .table-responsive diff --git a/app/views/registrar/invoices/index.haml b/app/views/registrar/invoices/index.haml index 9ed8b91d5..76a2966b5 100644 --- a/app/views/registrar/invoices/index.haml +++ b/app/views/registrar/invoices/index.haml @@ -57,7 +57,7 @@ %th{class: 'col-xs-3'}= t(:total) %tbody - @invoices.each do |invoice| - %tr.invoice + %tr %td= link_to(invoice, [:registrar, invoice]) - if invoice.paid? %td= l invoice.receipt_date diff --git a/app/views/registrar/invoices/partials/_banklinks.haml b/app/views/registrar/invoices/partials/_banklinks.haml index 84f6e1399..d9cbe1f21 100644 --- a/app/views/registrar/invoices/partials/_banklinks.haml +++ b/app/views/registrar/invoices/partials/_banklinks.haml @@ -3,5 +3,5 @@ - locals[:payment_channels].each do |meth| - meth = meth.strip - = link_to registrar_payment_with_path(meth, invoice_id: params[:id]) do + = link_to registrar_payment_with_path(meth, invoice_id: params[:id]), id: meth do = image_tag("#{meth}.png") diff --git a/app/views/registrar/invoices/partials/_payment_orders.haml b/app/views/registrar/invoices/partials/_payment_orders.haml new file mode 100644 index 000000000..d418ea1ac --- /dev/null +++ b/app/views/registrar/invoices/partials/_payment_orders.haml @@ -0,0 +1,19 @@ +%h4= "Payment Orders" +%hr +.table-responsive + %table.table.table-hover.table-condensed + %thead + %tr + %th{class: 'col-xs-1'}= "#" + %th{class: 'col-xs-1'}= "Channel" + %th{class: 'col-xs-2'}= "Status" + %th{class: 'col-xs-3'}= "Initiated" + %th{class: 'col-xs-4'}= "Notes" + %tbody + - @invoice.payment_orders.each do |payment_order| + %tr + %td= payment_order.id + %td= payment_order.channel + %td= payment_order.status + %td= payment_order.created_at + %td= payment_order.notes diff --git a/app/views/registrar/invoices/show.haml b/app/views/registrar/invoices/show.haml index 66a025eaf..5e6104091 100644 --- a/app/views/registrar/invoices/show.haml +++ b/app/views/registrar/invoices/show.haml @@ -17,4 +17,4 @@ - if @invoice.payable? .row.semifooter - .col-md-6-offset-6.text-right= render 'registrar/invoices/partials/banklinks', locals: { payment_channels: PaymentOrders::PAYMENT_METHODS } + .col-md-6-offset-6.text-right= render 'registrar/invoices/partials/banklinks', locals: { payment_channels: PaymentOrder::CUSTOMER_PAYMENT_METHODS } diff --git a/app/views/registrar/keyrelays/show.haml b/app/views/registrar/keyrelays/show.haml deleted file mode 100644 index 399c64925..000000000 --- a/app/views/registrar/keyrelays/show.haml +++ /dev/null @@ -1,64 +0,0 @@ -= render 'shared/title', name: t(:keyrelay) - -.row - .col-md-8 - = form_tag registrar_keyrelay_path, class: 'form-horizontal', method: :post, multipart: true do - .form-group - .col-md-3.control-label - = label_tag :domain_name, t(:domain_name), class: 'required' - .col-md-7 - = text_field_tag :domain_name, params[:domain_name], - class: 'form-control', autocomplete: 'off', required: true - - .form-group - .col-md-3.control-label - = label_tag :password, t(:password), class: 'required' - .col-md-7 - = text_field_tag :password, params[:password], - class: 'form-control', autocomplete: 'off', required: true - - .form-group - .col-md-3.control-label - = label_tag :expiry, t(:expiry), class: 'required' - .col-md-7 - = text_field_tag :expiry, params[:expiry], - class: 'form-control', autocomplete: 'off', required: true - - .form-group - .col-md-3.control-label - = label_tag :key_data_flags, t(:flag), class: 'required' - .col-md-7 - = select_tag :key_data_flags, - options_for_select(Depp::Dnskey::FLAGS, params['key_data_flags']), {class: 'form-control'} - - .form-group - .col-md-3.control-label - = label_tag :key_data_protocol, t(:protocol), class: 'required' - .col-md-7 - = select_tag :key_data_protocol, - options_for_select(Depp::Dnskey::PROTOCOLS, params['key_data_protocol']), - {class: 'form-control'} - - .form-group - .col-md-3.control-label - = label_tag :key_data_alg, t(:algorithm), class: 'required' - .col-md-7 - = select_tag :key_data_alg, - options_for_select(Depp::Dnskey::ALGORITHMS, params['key_data_alg']), {class: 'form-control'} - - .form-group - .col-md-3.control-label - = label_tag :key_data_public_key, t(:public_key), class: 'required' - .col-md-7 - = text_field_tag :key_data_public_key, params['key_data_public_key'], - class: 'form-control', required: true - - .form-group - .col-md-3.control-label - = label_tag :legal_document, t(:legal_document) - .col-md-7 - = file_field_tag :legal_document - - .form-group - .col-md-10.text-right - %button.btn.btn-warning= t(:upload_key) diff --git a/app/views/registrar/payments/pay.html.haml b/app/views/registrar/payments/pay.html.haml index 8e759f9ea..dd3fc982f 100644 --- a/app/views/registrar/payments/pay.html.haml +++ b/app/views/registrar/payments/pay.html.haml @@ -2,8 +2,8 @@ = t('registrar.invoices.redirected_to_intermediary') .payment-form - = form_tag @payment.form_url, method: :post do - - @payment.form_fields.each do |k, v| + = form_tag @payment_order.form_url, method: :post do + - @payment_order.form_fields.each do |k, v| = hidden_field_tag k, v = submit_tag t('registrar.invoices.go_to_intermediary') diff --git a/app/views/registrar/polls/show.haml b/app/views/registrar/polls/show.haml index c4c337749..4ff116b81 100644 --- a/app/views/registrar/polls/show.haml +++ b/app/views/registrar/polls/show.haml @@ -10,8 +10,6 @@ .panel-heading.clearfix .pull-left= t('message_no', id: msg_q['id']) .pull-right - - if @data.css('panData').any? # this is a keyrelay request - = link_to(t(:confirm), 'javascript: void(0);', class: 'btn btn-warning btn-xs js-keyrelay-confirm') - if @data.css('trnData trStatus').any? # this is a transfer request - unless ['serverApproved', 'clientApproved'].include?(@data.css('trStatus').first.text) = link_to(t(:confirm), 'javascript: void(0);', class: 'btn btn-warning btn-xs js-transfer-confirm') @@ -25,53 +23,14 @@ %dd= @data.css('qDate').text %dl.dl-horizontal - / keyrelay - - if @data.css('panData').any? - %dt= t(:domain_name) - %dd= @data.css('name').text - - %dt= t(:authinfo_pw) - %dd= @data.css('pw').text - - - if @data.css('relative').text.present? - %dt= t(:expiry_relative) - %dd= @data.css('relative').text - - - if @data.css('absolute').text.present? - %dt= t(:expiry_absolute) - %dd= @data.css('absolute').text - - %dt paDate - %dd= @data.css('paDate').text - - %dt= t(:flag) - %dd= @data.css('flags').text - - %dt= t(:protocol) - %dd= @data.css('protocol').text - - %dt= t(:algorithm) - %dd= @data.css('alg').text - - %dt= t(:public_key) - %dd= @data.css('pubKey').text - - = form_tag confirm_keyrelay_registrar_poll_path, class: 'js-keyrelay-form' do + - if @data.css('trnData trStatus').any? # this is a transfer request + = form_tag confirm_transfer_registrar_poll_path, class: 'js-transfer-form' do = hidden_field_tag 'domain[name]', @data.css('name').text - = hidden_field_tag 'domain[dnskeys_attributes][0][flags]', @data.css('flags').text - = hidden_field_tag 'domain[dnskeys_attributes][0][protocol]', @data.css('protocol').text - = hidden_field_tag 'domain[dnskeys_attributes][0][alg]', @data.css('alg').text - = hidden_field_tag 'domain[dnskeys_attributes][0][public_key]', @data.css('pubKey').text - - else - - if @data.css('trnData trStatus').any? # this is a transfer request - = form_tag confirm_transfer_registrar_poll_path, class: 'js-transfer-form' do - = hidden_field_tag 'domain[name]', @data.css('name').text - - - @data.css('trnData').children.each do |x| - - next if x.blank? - %dt= t(x.name) - %dd= x.text + - @data.css('trnData').children.each do |x| + - next if x.blank? + %dt= t(x.name) + %dd= x.text - else .row .col-sm-12 @@ -83,9 +42,6 @@ :coffee load_listener = -> - $(".js-keyrelay-confirm").on "click", -> - $(".js-keyrelay-form").submit() - $(".js-transfer-confirm").on "click", -> $(".js-transfer-form").submit() window.addEventListener 'load', load_listener diff --git a/app/views/registrar/xml_consoles/epp_requests/domain/client_hold.xml b/app/views/registrar/xml_consoles/epp_requests/domain/client_hold.xml new file mode 100644 index 000000000..fcafec538 --- /dev/null +++ b/app/views/registrar/xml_consoles/epp_requests/domain/client_hold.xml @@ -0,0 +1,15 @@ + + + + + + example.ee + + + + + + timo-1579351654 + + diff --git a/app/views/registrar/xml_consoles/epp_requests/keyrelay/keyrelay.xml b/app/views/registrar/xml_consoles/epp_requests/keyrelay/keyrelay.xml deleted file mode 100644 index 4a8773cac..000000000 --- a/app/views/registrar/xml_consoles/epp_requests/keyrelay/keyrelay.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - example6.ee - - 256 - 3 - 8 - cmlraXN0aGViZXN0 - - - 7521f360ae480e67c3096e4c046beb84 - - - P1D - - - - dGVzdCBmYWlsCg== - - 1422542244 - - diff --git a/app/views/registrar/xml_consoles/show.haml b/app/views/registrar/xml_consoles/show.haml index f96b67738..bb66116ee 100644 --- a/app/views/registrar/xml_consoles/show.haml +++ b/app/views/registrar/xml_consoles/show.haml @@ -29,6 +29,9 @@ , %a.js-load-xml{href: 'javascript:void(0)', data: {obj: 'domain', epp_action: 'delete'}} Delete + , + %a.js-load-xml{href: 'javascript:void(0)', data: {obj: 'domain', epp_action: 'client_hold'}} + Remove Client Hold %h4 Poll %a.js-load-xml{href: 'javascript:void(0)', data: {obj: 'poll', epp_action: 'poll'}} diff --git a/bin/bundle b/bin/bundle index 66e9889e8..8bfc37be6 100755 --- a/bin/bundle +++ b/bin/bundle @@ -1,3 +1,3 @@ #!/usr/bin/env ruby -ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __dir__) load Gem.bin_path('bundler', 'bundle') diff --git a/bin/rails b/bin/rails index 5191e6927..073966023 100755 --- a/bin/rails +++ b/bin/rails @@ -1,4 +1,4 @@ #!/usr/bin/env ruby -APP_PATH = File.expand_path('../../config/application', __FILE__) +APP_PATH = File.expand_path('../config/application', __dir__) require_relative '../config/boot' require 'rails/commands' diff --git a/bin/rspec b/bin/rspec deleted file mode 100755 index 8bc84617e..000000000 --- a/bin/rspec +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env ruby -# -# This file was generated by Bundler. -# -# The application 'rspec' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -require 'pathname' -ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', - Pathname.new(__FILE__).realpath) - -require 'rubygems' -require 'bundler/setup' - -load Gem.bin_path('rspec-core', 'rspec') diff --git a/bin/setup b/bin/setup old mode 100644 new mode 100755 index acdb2c138..ab3c84d9b --- a/bin/setup +++ b/bin/setup @@ -1,29 +1,38 @@ #!/usr/bin/env ruby +# frozen_string_literal: true + require 'pathname' +include FileUtils # path to your application root. -APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) +APP_ROOT = Pathname.new File.expand_path('../../', __dir__) -Dir.chdir APP_ROOT do +def system!(*args) + system(*args) || abort("\n== Command #{args} failed ==") +end + +chdir APP_ROOT do # This script is a starting point to setup your application. - # Add necessary setup steps to this file: + # Add necessary setup steps to this file. - puts "== Installing dependencies ==" - system "gem install bundler --conservative" - system "bundle check || bundle install" + puts '== Installing dependencies ==' + system! 'gem install bundler --conservative' + system('bundle check') || system!('bundle install') - # puts "\n== Copying sample files ==" - # unless File.exist?("config/database.yml") - # system "cp config/database.yml.sample config/database.yml" - # end + # Install JavaScript dependencies if using Yarn + # system('bin/yarn') + + puts "\n== Copying sample files ==" + unless File.exist?('config/database.yml') + system! 'cp config/database.yml.sample config/database.yml' + end puts "\n== Preparing database ==" - system "bin/rake db:setup" + system! 'bin/rails db:setup' puts "\n== Removing old logs and tempfiles ==" - system "rm -f log/*" - system "rm -rf tmp/cache" + system! 'bin/rails log:clear tmp:clear' puts "\n== Restarting application server ==" - system "touch tmp/restart.txt" + system! 'bin/rails restart' end diff --git a/bin/setup_with_build_deps b/bin/setup_with_build_deps new file mode 100755 index 000000000..bbd3707db --- /dev/null +++ b/bin/setup_with_build_deps @@ -0,0 +1,56 @@ +#!/usr/bin/env ruby +require 'pathname' +require 'fileutils' + +# path to your application root. +APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) + + +def system!(*args) + system(*args) || abort("\n== Command #{args} failed ==") +end + +def effective_user_id + uid = `id -u` + uid.strip! +end + +Dir.chdir APP_ROOT do + puts '== Installing application build deps ==' + sudo_prefix = '' + sudo_prefix = "sudo" unless effective_user_id == '0' + system! "#{sudo_prefix} apt-get update && #{sudo_prefix} apt-get -y --no-install-recommends install libxml2 libxml2-dev postgresql-client postgresql-client-common libpq-dev" + + puts "== Installing rbenv ruby manager to #{ENV['HOME']} ==" + unless Dir.exist?("#{ENV['HOME']}/.rbenv/") + system! 'git clone https://github.com/sstephenson/rbenv.git $HOME/.rbenv' + system! 'echo export PATH="$HOME/.rbenv/bin:$PATH" >> ~/.bashrc' + system! "echo 'eval $(rbenv init -)' >> ~/.bashrc" + end + + unless Dir.exist?("#{ENV['HOME']}/.rbenv/plugins/ruby-build/") + system! 'git clone https://github.com/sstephenson/ruby-build.git $HOME/.rbenv/plugins/ruby-build' + system! 'echo export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH" >> ~/.bashrc' + end + unless Dir.exist?("#{ENV['HOME']}/.rbenv/plugins/rbenv-default-gems/") + system! 'git clone https://github.com/rbenv/rbenv-default-gems.git $HOME/.rbenv/plugins/rbenv-default-gems' + unless File.exist?("#{ENV['HOME']}/.rbenv/default-gems") + system! 'echo "bundler" > ~/.rbenv/default-gems' + end + end + + # Include RBENV in path + ENV['PATH'] = ENV['HOME'] + "/.rbenv/bin:" + ENV['HOME'] + "/.rbenv/plugins/ruby-build/bin:" + ENV['PATH'] + NEEDED_RUBY_VERSION = `cat .ruby-version`.freeze + + if `!bundle check` == false + system! "#{SUDO_PREFIX} apt-get -y --no-install-recommends install libreadline-dev" + puts 'Installing Ruby: ' + NEEDED_RUBY_VERSION + system!('rbenv install ' + NEEDED_RUBY_VERSION) + system!('rbenv rehash') + else + puts 'Ruby ' + NEEDED_RUBY_VERSION + 'already installed' + end + puts 'Now running setup' + exec('./bin/setup') +end diff --git a/bin/update b/bin/update new file mode 100755 index 000000000..a8e4462f2 --- /dev/null +++ b/bin/update @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +require 'pathname' +require 'fileutils' +include FileUtils + +# path to your application root. +APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) + +def system!(*args) + system(*args) || abort("\n== Command #{args} failed ==") +end + +chdir APP_ROOT do + # This script is a way to update your development environment automatically. + # Add necessary update steps to this file. + + puts '== Installing dependencies ==' + system! 'gem install bundler --conservative' + system('bundle check') || system!('bundle install') + + puts "\n== Updating database ==" + system! 'bin/rails db:migrate' + + puts "\n== Removing old logs and tempfiles ==" + system! 'bin/rails log:clear tmp:clear' + + puts "\n== Restarting application server ==" + system! 'bin/rails restart' +end diff --git a/bin/update-repo b/bin/update-repo deleted file mode 100755 index ae0cd536b..000000000 --- a/bin/update-repo +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -# -# Update repo -# - -# cd to Rails root directory -cd "$(dirname "$0")"; cd .. - -git pull origin master &> /dev/null -git reset --hard &> /dev/null -unset GIT_DIR GIT_WORK_TREE diff --git a/bin/yarn b/bin/yarn new file mode 100755 index 000000000..adabdd976 --- /dev/null +++ b/bin/yarn @@ -0,0 +1,9 @@ +#!/usr/bin/env ruby +APP_ROOT = File.expand_path('..', __dir__) +Dir.chdir(APP_ROOT) do + exec 'yarnpkg', *ARGV +rescue Errno::ENOENT + $stderr.puts 'Yarn executable was not detected in the system.' + $stderr.puts 'Download Yarn at https://yarnpkg.com/en/docs/install' + exit 1 +end diff --git a/config.ru b/config.ru index 4fa72a37f..ec46ca9f1 100644 --- a/config.ru +++ b/config.ru @@ -1,6 +1,6 @@ # This file is used by Rack-based servers to start the application. -require ::File.expand_path('../config/environment', __FILE__) +require_relative 'config/environment' run Rails.application # turn automatic que temp off diff --git a/config/app.yml b/config/app.yml deleted file mode 100644 index 763da3373..000000000 --- a/config/app.yml +++ /dev/null @@ -1,74 +0,0 @@ -# config/app.yml for rails-settings-cached -defaults: &defaults - admin_contacts_min_count: 1 - admin_contacts_max_count: 10 - tech_contacts_min_count: 1 - tech_contacts_max_count: 10 - orphans_contacts_in_months: 6 - expire_pending_confirmation: 48 - - ds_digest_type: 2 - ds_data_allowed: false - key_data_allowed: true - - dnskeys_min_count: 0 - dnskeys_max_count: 9 - ns_min_count: 2 - ns_max_count: 11 - - transfer_wait_time: 0 - request_confrimation_on_registrant_change_enabled: true - request_confirmation_on_domain_deletion_enabled: true - address_processing: true - default_language: en - nameserver_required: false - - client_side_status_editing_enabled: false - - invoice_number_min: 131050 - invoice_number_max: 149999 - directo_monthly_number_min: 309901 - directo_monthly_number_max: 309999 - directo_monthly_number_last: 309901 - days_to_keep_invoices_active: 30 - minimum_deposit: 0.0 - directo_receipt_payment_term: R - directo_receipt_product_name: ETTEM06 - directo_sales_agent: JAANA - - days_to_renew_domain_before_expire: 90 - expire_warning_period: 15 - redemption_grace_period: 30 - expiration_reminder_mail: 2 - - registrar_ip_whitelist_enabled: false - api_ip_whitelist_enabled: false - - registry_juridical_name: "Eesti Interneti SA" - registry_reg_no: "90010019" - registry_email: "info@internet.ee" - registry_billing_email: "info@internet.ee" - registry_phone: "+372 727 1000" - registry_country_code: "EE" - registry_state: "Harjumaa" - registry_street: "Paldiski mnt 80" - registry_city: "Tallinn" - registry_zip: "10617" - registry_vat_no: "EE101286464" - registry_url: "www.internet.ee" - registry_vat_prc: 0.2 - registry_iban: "EE557700771000598731" - registry_bank: "LHV Pank" - registry_bank_code: "689" - registry_swift: "LHVBEE22" - registry_invoice_contact: "Martti Õigus" - registry_whois_disclaimer: "Search results may not be used for commercial, advertising, recompilation, repackaging, redistribution, reuse, obscuring or other similar activities." - -development: - <<: *defaults - -test: - <<: *defaults - -production: - <<: *defaults diff --git a/config/application.rb b/config/application.rb index 21d7e9dd0..5f4481512 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,15 +1,8 @@ -require File.expand_path('../boot', __FILE__) +require_relative 'boot' -# Pick the frameworks you want: -require 'active_model/railtie' -require 'active_record/railtie' -require 'action_controller/railtie' -require 'action_mailer/railtie' -require 'action_view/railtie' -require 'sprockets/railtie' -require 'csv' require 'rails/all' -# require "rails/test_unit/railtie" +require 'English' +require 'csv' # Require the gems listed in Gemfile, including any gems # you've limited to :test, :development, or :production. @@ -23,6 +16,9 @@ end module DomainNameRegistry class Application < Rails::Application + config.load_defaults 6.0 + config.autoloader = :classic # Do not use zeitwerk for now + # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. @@ -43,21 +39,6 @@ module DomainNameRegistry config.eager_load_paths << config.root.join('lib', 'validators') config.watchable_dirs['lib'] = %i[rb] - # Add the fonts path - config.assets.paths << Rails.root.join('vendor', 'assets', 'fonts') - - # Precompile additional assets - config.assets.precompile += %w(*.svg *.eot *.woff *.ttf) - config.assets.precompile += %w(admin-manifest.css admin-manifest.js) - config.assets.precompile += %w(registrar-manifest.css registrar-manifest.js) - config.assets.precompile += %w(registrant-manifest.css registrant-manifest.js) - - # Active Record used to suppresses errors raised within - # `after_rollback`/`after_commit` callbacks and only printed them to the logs. - # In the next version, these errors will no longer be suppressed. - # Instead, the errors will propagate normally just like in other Active Record callbacks. - config.active_record.raise_in_transactional_callbacks = true - config.active_record.schema_format = :sql config.generators do |g| @@ -65,7 +46,6 @@ module DomainNameRegistry g.javascripts false g.helper false g.template_engine :erb - g.jbuilder false g.test_framework nil end @@ -77,9 +57,6 @@ module DomainNameRegistry config.action_mailer.perform_deliveries = true config.action_mailer.raise_delivery_errors = true - # Override "spec/mailers/previews" that RSpec sets - config.action_mailer.preview_path = "#{Rails.root}/test/mailers/previews" - config.action_mailer.smtp_settings = { address: ENV['smtp_address'], port: ENV['smtp_port'], @@ -97,7 +74,13 @@ module DomainNameRegistry config.action_view.default_form_builder = 'DefaultFormBuilder' config.secret_key_base = Figaro.env.secret_key_base + + # Using `Rails.application.config.active_record.belongs_to_required_by_default` in + # `new_framework_defaults.rb` has no effect in Rails 5.0.x. + # https://github.com/rails/rails/issues/23589 + # https://stackoverflow.com/questions/38850712/rails-5-belongs-to-required-by-default-doesnt-work + # Not supported by `paper_trail` gem < 5.0 + # https://github.com/paper-trail-gem/paper_trail/issues/682 + config.active_record.belongs_to_required_by_default = false end end - -require 'validates_email_format_of' diff --git a/config/application-example.yml b/config/application.yml.sample similarity index 96% rename from config/application-example.yml rename to config/application.yml.sample index 0738a9278..2cd19b768 100644 --- a/config/application-example.yml +++ b/config/application.yml.sample @@ -50,10 +50,6 @@ webclient_cert_common_name: 'webclient' # and returns 2306 "Parameter value policy error" contact_org_enabled: 'false' -# Overwrite rack default trusted proxies list in order to -# enable test external interfaces EPP/REPP from webserver network -# eis_trusted_proxies: '1.1.1.1,2.2.2.2' #ips, separated with commas - # Enable iptables counter updater # iptables_counter_enabled: 'true' # iptables_server_ip: '127.0.0.1' @@ -152,6 +148,11 @@ action_mailer_default_port: # default: no port (80) action_mailer_default_from: # no-reply@example.com action_mailer_force_delete_from: # `From` header for `DomainDeleteMailer#forced` email +lhv_p12_keystore: +lhv_keystore_password: +lhv_ca_file: # Needed only in dev mode +lhv_dev_mode: 'false' + # Since the keys for staging are absent from the repo, we need to supply them separate for testing. test: payments_seb_bank_certificate: 'test/fixtures/files/seb_bank_cert.pem' @@ -161,6 +162,9 @@ test: action_mailer_default_host: 'registry.test' action_mailer_default_from: 'no-reply@registry.test' action_mailer_force_delete_from: 'legal@registry.test' + lhv_p12_keystore: 'test/fixtures/files/keystore.p12' + lhv_keystore_password: 'testtest' + legal_documents_dir: 'test/fixtures/files' # Airbrake // Errbit: airbrake_host: "https://your-errbit-host.ee" diff --git a/config/boot.rb b/config/boot.rb index 5e5f0c1fa..da8896b7b 100644 --- a/config/boot.rb +++ b/config/boot.rb @@ -1,4 +1,4 @@ -# Set up gems listed in the Gemfile. -ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) -require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) +require 'bundler/setup' # Set up gems listed in the Gemfile. +require 'bootsnap/setup' diff --git a/config/cable.yml b/config/cable.yml new file mode 100644 index 000000000..858bb1f14 --- /dev/null +++ b/config/cable.yml @@ -0,0 +1,10 @@ +development: + adapter: async + +test: + adapter: async + +production: + adapter: redis + url: redis://localhost:6379/1 + channel_prefix: domain_name_registry_production diff --git a/config/database-example.yml b/config/database.yml.sample similarity index 92% rename from config/database-example.yml rename to config/database.yml.sample index ca47a9979..a3eab11ed 100644 --- a/config/database-example.yml +++ b/config/database.yml.sample @@ -1,7 +1,7 @@ # # EPP, REPP, Admin and Registrar config # -# Registrant example is at database-example-registrant.yml file +# Registrant example is at database_registrant.yml.sample file default: &default adapter: postgresql diff --git a/config/database-example-development.yml b/config/database_development.yml.sample similarity index 100% rename from config/database-example-development.yml rename to config/database_development.yml.sample diff --git a/config/database-example-registrant.yml b/config/database_registrant.yml.sample similarity index 100% rename from config/database-example-registrant.yml rename to config/database_registrant.yml.sample diff --git a/config/database-travis.yml b/config/database_travis.yml similarity index 100% rename from config/database-travis.yml rename to config/database_travis.yml diff --git a/config/deploy-example.rb b/config/deploy.rb.sample similarity index 100% rename from config/deploy-example.rb rename to config/deploy.rb.sample diff --git a/config/environment.rb b/config/environment.rb index ee8d90dc6..426333bb4 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -1,5 +1,5 @@ # Load the Rails application. -require File.expand_path('../application', __FILE__) +require_relative 'application' # Initialize the Rails application. Rails.application.initialize! diff --git a/config/environments/development-example.rb b/config/environments/development-example.rb deleted file mode 100644 index 59efe01d9..000000000 --- a/config/environments/development-example.rb +++ /dev/null @@ -1,50 +0,0 @@ -Rails.application.configure do - # Settings specified here will take precedence over those in config/application.rb. - - # In the development environment your application's code is reloaded on - # every request. This slows down response time but is perfect for development - # since you don't have to restart the web server when you make code changes. - config.cache_classes = false - - # Do not eager load code on boot. - config.eager_load = false - - # Show full error reports and disable caching. - config.consider_all_requests_local = true - config.action_controller.perform_caching = false - - # Print deprecation notices to the Rails logger. - config.active_support.deprecation = :log - - config.logger = ActiveSupport::Logger.new(nil) - - # Raise an error on page load if there are pending migrations. - config.active_record.migration_error = :page_load - - # Debug mode disables concatenation and preprocessing of assets. - # This option may cause significant delays in view rendering with a large - # number of complex assets. - config.assets.debug = false - - # Adds additional error checking when serving assets at runtime. - # Checks for improperly declared sprockets dependencies. - # Raises helpful error messages. - config.assets.raise_runtime_errors = true - - config.action_view.raise_on_missing_translations = true - - # for finding database optimization - config.after_initialize do - Bullet.enable = true - Bullet.bullet_logger = true - Bullet.console = true - Bullet.rails_logger = true - Bullet.add_footer = true - Bullet.unused_eager_loading_enable = false - end -end - -# In this mode, any jobs you queue will be run in the same thread, synchronously -# (that is, MyJob.enqueue runs the job and won't return until it's completed). -# This makes your application's behavior easier to test -Que.mode = :sync diff --git a/config/environments/development.rb.sample b/config/environments/development.rb.sample new file mode 100644 index 000000000..377f2cbbd --- /dev/null +++ b/config/environments/development.rb.sample @@ -0,0 +1,70 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # In the development environment your application's code is reloaded on + # every request. This slows down response time but is perfect for development + # since you don't have to restart the web server when you make code changes. + config.cache_classes = false + + # Do not eager load code on boot. + config.eager_load = false + + # Show full error reports. + config.consider_all_requests_local = true + + # Enable/disable caching. By default caching is disabled. + # Run rails dev:cache to toggle caching. + if Rails.root.join('tmp', 'caching-dev.txt').exist? + config.action_controller.perform_caching = true + config.action_controller.enable_fragment_cache_logging = true + + config.cache_store = :memory_store + config.public_file_server.headers = { + 'Cache-Control' => "public, max-age=#{2.days.to_i}" + } + else + config.action_controller.perform_caching = false + + config.cache_store = :null_store + end + + # Store uploaded files on the local file system (see config/storage.yml for options). + config.active_storage.service = :local + + # Don't care if the mailer can't send. + config.action_mailer.raise_delivery_errors = false + + config.action_mailer.perform_caching = false + + # Print deprecation notices to the Rails logger. + config.active_support.deprecation = :log + + # Raise an error on page load if there are pending migrations. + config.active_record.migration_error = :page_load + + # Highlight code that triggered database queries in logs. + config.active_record.verbose_query_logs = true + + # Debug mode disables concatenation and preprocessing of assets. + # This option may cause significant delays in view rendering with a large + # number of complex assets. + config.assets.debug = true + + # Suppress logger output for asset requests. + config.assets.quiet = true + + # Allow any host to access development + config.hosts.clear + + # Raises error for missing translations. + # config.action_view.raise_on_missing_translations = true + + # Use an evented file watcher to asynchronously detect changes in source code, + # routes, locales, etc. This feature depends on the listen gem. + config.file_watcher = ActiveSupport::EventedFileUpdateChecker +end + +# In this mode, any jobs you queue will be run in the same thread, synchronously +# (that is, MyJob.enqueue runs the job and won't return until it's completed). +# This makes your application's behavior easier to test +Que.mode = :sync diff --git a/config/environments/production.rb b/config/environments/production.rb index 11a620e35..6e13ea1f7 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -19,8 +19,7 @@ Rails.application.configure do # For large-scale production use, consider using a caching reverse proxy like nginx, varnish or squid. # config.action_dispatch.rack_cache = true - # Disable Rails's static asset server (Apache or nginx will already do this). - config.serve_static_files = false + config.public_file_server.enabled = false # Compress JavaScripts and CSS. config.assets.js_compressor = Uglifier.new(harmony: true) @@ -29,38 +28,37 @@ Rails.application.configure do # Do not fallback to assets pipeline if a precompiled asset is missed. config.assets.compile = false - # Generate digests for assets URLs. - config.assets.digest = true + # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb - # Version of your assets, change this if you want to expire all your assets. - config.assets.version = '1.0' + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + # config.action_controller.asset_host = 'http://assets.example.com' # Specifies the header that your server uses for sending files. - # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache - # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx + # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache + # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX + + # Mount Action Cable outside main process or domain + # config.action_cable.mount_path = nil + # config.action_cable.url = 'wss://example.com/cable' + # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ] # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. # config.force_ssl = true - # Set to :debug to see everything in the log. - config.log_level = :info + # Use the lowest log level to ensure availability of diagnostic information + # when problems arise. + config.log_level = :debug # Prepend all log lines with the following tags. - config.log_tags = [:subdomain, :uuid, :remote_ip] - - # Use a different logger for distributed setups. - require 'syslog/logger' - config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new(ENV['app_name'] || 'registry')) + config.log_tags = [:request_id, :subdomain, :remote_ip] # Use a different cache store in production. # config.cache_store = :mem_cache_store - # Enable serving of images, stylesheets, and JavaScripts from an asset server. - # config.action_controller.asset_host = "http://assets.example.com" - - # Precompile additional assets. - # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. - # config.assets.precompile += %w( search.js ) + # Use a real queuing backend for Active Job (and separate queues per environment) + # config.active_job.queue_adapter = :resque + # config.active_job.queue_name_prefix = "domain_name_registry_#{Rails.env}" + config.action_mailer.perform_caching = false # Ignore bad email addresses and do not raise email delivery errors. # Set this to true and configure the email server for immediate delivery to raise delivery errors. @@ -71,19 +69,26 @@ Rails.application.configure do config.i18n.fallbacks = true # Send deprecation notices to registered listeners. - config.active_support.deprecation = :log - - # Disable automatic flushing of the log to improve performance. - # config.autoflush_log = false + config.active_support.deprecation = :notify # Use default logging formatter so that PID and timestamp are not suppressed. config.log_formatter = ::Logger::Formatter.new + # Use a different logger for distributed setups. + require 'syslog/logger' + config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new(ENV['app_name'] || 'registry')) + + if ENV["RAILS_LOG_TO_STDOUT"].present? + logger = ActiveSupport::Logger.new(STDOUT) + logger.formatter = config.log_formatter + config.logger = ActiveSupport::TaggedLogging.new(logger) + end + # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false end -# In off mode, queueing a job will simply insert it into the database - -# the current process will make no effort to run it. +# In off mode, queueing a job will simply insert it into the database - +# the current process will make no effort to run it. # You should use this if you want to use a dedicated process to work tasks -Que.mode = :off +Que.mode = :off diff --git a/config/environments/staging-example.rb b/config/environments/staging.rb.sample similarity index 100% rename from config/environments/staging-example.rb rename to config/environments/staging.rb.sample diff --git a/config/environments/test.rb b/config/environments/test.rb index 119f6d815..c55e59e31 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -1,24 +1,40 @@ + Rails.application.configure do + # $VERBOSE = nil # Settings specified here will take precedence over those in config/application.rb. + # The test environment is used exclusively to run your application's + # test suite. You never need to work with it otherwise. Remember that + # your test database is "scratch space" for the test suite and is wiped + # and recreated between test runs. Don't rely on the data there! config.cache_classes = true - config.eager_load = false - config.serve_static_files = true - config.static_cache_control = 'public, max-age=3600' + # Do not eager load code on boot. This avoids loading your whole application + # just for the purpose of running a single test. If you are using a tool that + # preloads Rails for running tests, you may have to set it to true. + config.eager_load = false config.consider_all_requests_local = true config.action_controller.perform_caching = false + # Raise exceptions instead of rendering exception templates. config.action_dispatch.show_exceptions = false + # Disable request forgery protection in test environment. config.action_controller.allow_forgery_protection = false + config.action_mailer.perform_caching = false + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test - config.active_support.test_order = :random - config.active_support.deprecation = :stderr - config.logger = ActiveSupport::Logger.new(nil) + config.action_mailer.raise_delivery_errors = false + # Print deprecation notices to the stderr. + config.active_support.deprecation = :silence + + # Raises error for missing translations config.action_view.raise_on_missing_translations = true # If set to :null_store, Setting.x returns nil after first spec runs (database is emptied) diff --git a/config/initializers/airbrake.rb b/config/initializers/airbrake.rb new file mode 100644 index 000000000..abfe408c1 --- /dev/null +++ b/config/initializers/airbrake.rb @@ -0,0 +1,21 @@ +Airbrake.configure do |config| + config.host = ENV['airbrake_host'] + config.project_id = ENV['airbrake_project_id'] + config.project_key = ENV['airbrake_project_key'] + config.root_directory = Rails.root + config.job_stats = false + config.query_stats = false + config.performance_stats = false + config.logger = + if ENV['RAILS_LOG_TO_STDOUT'].present? + Logger.new(STDOUT, level: Rails.logger.level) + else + Logger.new( + Rails.root.join('log', 'airbrake.log'), + level: Rails.logger.level + ) + end + config.environment = ENV['airbrake_env'] || Rails.env + config.ignore_environments = %w[test] + config.blocklist_keys = Rails.application.config.filter_parameters +end diff --git a/config/initializers/application_controller_renderer.rb b/config/initializers/application_controller_renderer.rb new file mode 100644 index 000000000..89d2efab2 --- /dev/null +++ b/config/initializers/application_controller_renderer.rb @@ -0,0 +1,8 @@ +# Be sure to restart your server when you modify this file. + +# ActiveSupport::Reloader.to_prepare do +# ApplicationController.renderer.defaults.merge!( +# http_host: 'example.org', +# https: false +# ) +# end diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index d1a94d7c6..d5a05217a 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -1 +1,12 @@ -Rails.application.config.assets.precompile += %w( login.css registrar-manifest.css shared/pdf.css ) +# Be sure to restart your server when you modify this file. + +Rails.application.configure do + # Version of your assets, change this if you want to expire all your assets. + config.assets.version = '1.0' + + # Add additional assets to the asset load path + config.assets.paths << Rails.root.join('vendor', 'assets', 'fonts', 'node_modules') + + # Precompile additional assets. + # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. +end diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb new file mode 100644 index 000000000..d3bcaa5ec --- /dev/null +++ b/config/initializers/content_security_policy.rb @@ -0,0 +1,25 @@ +# Be sure to restart your server when you modify this file. + +# Define an application-wide content security policy +# For further information see the following documentation +# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy + +# Rails.application.config.content_security_policy do |policy| +# policy.default_src :self, :https +# policy.font_src :self, :https, :data +# policy.img_src :self, :https, :data +# policy.object_src :none +# policy.script_src :self, :https +# policy.style_src :self, :https + +# # Specify URI for violation reports +# # policy.report_uri "/csp-violation-report-endpoint" +# end + +# If you are using UJS then enable automatic nonce generation +# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) } + +# Report CSP violations to a specified URI +# For further information see the following documentation: +# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only +# Rails.application.config.content_security_policy_report_only = true diff --git a/config/initializers/cookies_serializer.rb b/config/initializers/cookies_serializer.rb index 7f70458de..5a6a32d37 100644 --- a/config/initializers/cookies_serializer.rb +++ b/config/initializers/cookies_serializer.rb @@ -1,3 +1,5 @@ # Be sure to restart your server when you modify this file. +# Specify a serializer for the signed and encrypted cookie jars. +# Valid options are :json, :marshal, and :hybrid. Rails.application.config.action_dispatch.cookies_serializer = :json diff --git a/config/initializers/current_commit_hash.rb b/config/initializers/current_commit_hash.rb deleted file mode 100644 index b018b46fd..000000000 --- a/config/initializers/current_commit_hash.rb +++ /dev/null @@ -1 +0,0 @@ -CURRENT_COMMIT_HASH = `git rev-parse --short HEAD` diff --git a/config/initializers/eis_custom_rack.rb b/config/initializers/eis_custom_rack.rb deleted file mode 100644 index 9ddf40cde..000000000 --- a/config/initializers/eis_custom_rack.rb +++ /dev/null @@ -1,12 +0,0 @@ -# EIS custom rack hack in order to enable test external interfaces EPP/REPP inside webserver network -module Rack - class Request - def trusted_proxy?(ip) - if ENV['eis_trusted_proxies'] - ENV['eis_trusted_proxies'].split(',').map(&:strip).include?(ip) - else - ip =~ /\A127\.0\.0\.1\Z|\A(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\.|\A::1\Z|\Afd[0-9a-f]{2}:.+|\Alocalhost\Z|\Aunix\Z|\Aunix:/i - end - end - end -end diff --git a/config/initializers/errbit.rb b/config/initializers/errbit.rb deleted file mode 100644 index 3d4185834..000000000 --- a/config/initializers/errbit.rb +++ /dev/null @@ -1,22 +0,0 @@ -module Patches - module Airbrake - module SyncSender - def build_https(uri) - super.tap do |req| - req.verify_mode = OpenSSL::SSL::VERIFY_NONE - end - end - end - end -end - -Airbrake::SyncSender.prepend(::Patches::Airbrake::SyncSender) - -Airbrake.configure do |config| - config.host = ENV['airbrake_host'] - config.project_id = ENV['airbrake_project_id'] - config.project_key = ENV['airbrake_project_key'] - - config.environment = ENV['airbrake_env'] || Rails.env - config.ignore_environments = %w(development test) -end diff --git a/config/initializers/ext.rb b/config/initializers/ext.rb deleted file mode 100644 index 50b8b2791..000000000 --- a/config/initializers/ext.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'core_ext/array' -require 'gem_ext/builder' -require 'gem_ext/i18n' -require 'gem_ext/paper_trail' \ No newline at end of file diff --git a/config/initializers/figaro.rb b/config/initializers/figaro.rb index 44c830eea..c057f8eee 100644 --- a/config/initializers/figaro.rb +++ b/config/initializers/figaro.rb @@ -1,15 +1,7 @@ Figaro.require_keys(%w[ app_name - zonefile_export_dir secret_key_base devise_secret - crl_dir - ca_cert_path - ca_key_path - ca_key_password - webclient_ips - legal_documents_dir - bank_statement_import_dir time_zone action_mailer_default_host action_mailer_default_from diff --git a/config/initializers/kaminari.rb b/config/initializers/kaminari.rb new file mode 100644 index 000000000..d1ac7c117 --- /dev/null +++ b/config/initializers/kaminari.rb @@ -0,0 +1,3 @@ +Kaminari.configure do |config| + config.default_per_page = 75 +end diff --git a/config/initializers/kaminari_config.rb b/config/initializers/kaminari_config.rb deleted file mode 100644 index 2eeb4bab6..000000000 --- a/config/initializers/kaminari_config.rb +++ /dev/null @@ -1,10 +0,0 @@ -Kaminari.configure do |config| - config.default_per_page = 75 - # config.max_per_page = nil - # config.window = 4 - # config.outer_window = 0 - # config.left = 0 - # config.right = 0 - # config.page_method_name = :page - # config.param_name = :page -end diff --git a/config/initializers/money.rb b/config/initializers/money.rb index cb476b589..a52ff280d 100644 --- a/config/initializers/money.rb +++ b/config/initializers/money.rb @@ -1,4 +1,6 @@ MoneyRails.configure do |config| # Wrapper for Money#default_currency with additional functionality config.default_currency = :eur -end \ No newline at end of file + config.rounding_mode = BigDecimal::ROUND_HALF_EVEN + config.locale_backend = :i18n +end diff --git a/config/initializers/monkey_patches.rb b/config/initializers/monkey_patches.rb new file mode 100644 index 000000000..d342fb6b0 --- /dev/null +++ b/config/initializers/monkey_patches.rb @@ -0,0 +1,5 @@ +require 'core_monkey_patches/array' +require 'gem_monkey_patches/builder' +require 'gem_monkey_patches/i18n' +require 'gem_monkey_patches/paper_trail' +require 'gem_monkey_patches/ransack' diff --git a/config/initializers/new_framework_defaults.rb b/config/initializers/new_framework_defaults.rb new file mode 100644 index 000000000..2f9c3c5cb --- /dev/null +++ b/config/initializers/new_framework_defaults.rb @@ -0,0 +1,28 @@ +# Be sure to restart your server when you modify this file. +# +# This file contains migration options to ease your Rails 5.0 upgrade. +# +# Once upgraded flip defaults one by one to migrate to the new default. +# +# Read the Guide for Upgrading Ruby on Rails for more info on each option. + +# DEPRECATION WARNING: raise_on_unfiltered_parameters is deprecated and has no effect in Rails 5.1. +#Rails.application.config.action_controller.raise_on_unfiltered_parameters = true + +# Enable per-form CSRF tokens. Previous versions had false. +Rails.application.config.action_controller.per_form_csrf_tokens = true + +# Enable origin-checking CSRF mitigation. Previous versions had false. +Rails.application.config.action_controller.forgery_protection_origin_check = true + +# Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`. +# Previous versions had false. +ActiveSupport.to_time_preserves_timezone = true + +# Do not halt callback chains when a callback returns false. Previous versions had true. +# DEPRECATION WARNING: ActiveSupport.halt_callback_chains_on_return_false= is deprecated and +# will be removed in Rails 5.2. +#ActiveSupport.halt_callback_chains_on_return_false = false + +# Configure SSL options to enable HSTS with subdomains. Previous versions had false. +Rails.application.config.ssl_options = { hsts: { subdomains: true } } diff --git a/config/initializers/new_framework_defaults_5_1.rb b/config/initializers/new_framework_defaults_5_1.rb new file mode 100644 index 000000000..9010abd5c --- /dev/null +++ b/config/initializers/new_framework_defaults_5_1.rb @@ -0,0 +1,14 @@ +# Be sure to restart your server when you modify this file. +# +# This file contains migration options to ease your Rails 5.1 upgrade. +# +# Once upgraded flip defaults one by one to migrate to the new default. +# +# Read the Guide for Upgrading Ruby on Rails for more info on each option. + +# Make `form_with` generate non-remote forms. +Rails.application.config.action_view.form_with_generates_remote_forms = false + +# Unknown asset fallback will return the path passed in when the given +# asset is not present in the asset pipeline. +# Rails.application.config.assets.unknown_asset_fallback = false diff --git a/config/initializers/new_framework_defaults_5_2.rb b/config/initializers/new_framework_defaults_5_2.rb new file mode 100644 index 000000000..c383d072b --- /dev/null +++ b/config/initializers/new_framework_defaults_5_2.rb @@ -0,0 +1,38 @@ +# Be sure to restart your server when you modify this file. +# +# This file contains migration options to ease your Rails 5.2 upgrade. +# +# Once upgraded flip defaults one by one to migrate to the new default. +# +# Read the Guide for Upgrading Ruby on Rails for more info on each option. + +# Make Active Record use stable #cache_key alongside new #cache_version method. +# This is needed for recyclable cache keys. +# Rails.application.config.active_record.cache_versioning = true + +# Use AES-256-GCM authenticated encryption for encrypted cookies. +# Also, embed cookie expiry in signed or encrypted cookies for increased security. +# +# This option is not backwards compatible with earlier Rails versions. +# It's best enabled when your entire app is migrated and stable on 5.2. +# +# Existing cookies will be converted on read then written with the new scheme. +# Rails.application.config.action_dispatch.use_authenticated_cookie_encryption = true + +# Use AES-256-GCM authenticated encryption as default cipher for encrypting messages +# instead of AES-256-CBC, when use_authenticated_message_encryption is set to true. +# Rails.application.config.active_support.use_authenticated_message_encryption = true + +# Add default protection from forgery to ActionController::Base instead of in +# ApplicationController. +# Rails.application.config.action_controller.default_protect_from_forgery = true + +# Store boolean values are in sqlite3 databases as 1 and 0 instead of 't' and +# 'f' after migrating old data. +# Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true + +# Use SHA-1 instead of MD5 to generate non-sensitive digests, such as the ETag header. +# Rails.application.config.active_support.use_sha1_digests = true + +# Make `form_with` generate id attributes for any generated HTML tags. +# Rails.application.config.action_view.form_with_generates_ids = true diff --git a/config/initializers/new_framework_defaults_6_0.rb b/config/initializers/new_framework_defaults_6_0.rb new file mode 100644 index 000000000..998b2f346 --- /dev/null +++ b/config/initializers/new_framework_defaults_6_0.rb @@ -0,0 +1,45 @@ +# Be sure to restart your server when you modify this file. +# +# This file contains migration options to ease your Rails 6.0 upgrade. +# +# Once upgraded flip defaults one by one to migrate to the new default. +# +# Read the Guide for Upgrading Ruby on Rails for more info on each option. + +# Don't force requests from old versions of IE to be UTF-8 encoded. +Rails.application.config.action_view.default_enforce_utf8 = false + +# Embed purpose and expiry metadata inside signed and encrypted +# cookies for increased security. +# +# This option is not backwards compatible with earlier Rails versions. +# It's best enabled when your entire app is migrated and stable on 6.0. +# Rails.application.config.action_dispatch.use_cookies_with_metadata = true + +# Change the return value of `ActionDispatch::Response#content_type` to Content-Type header without modification. +Rails.application.config.action_dispatch.return_only_media_type_on_content_type = false + +# Return false instead of self when enqueuing is aborted from a callback. +Rails.application.config.active_job.return_false_on_aborted_enqueue = true + +# Send Active Storage analysis and purge jobs to dedicated queues. +# Rails.application.config.active_storage.queues.analysis = :active_storage_analysis +# Rails.application.config.active_storage.queues.purge = :active_storage_purge + +# When assigning to a collection of attachments declared via `has_many_attached`, replace existing +# attachments instead of appending. Use #attach to add new attachments without replacing existing ones. +# Rails.application.config.active_storage.replace_on_assign_to_many = true + +# Use ActionMailer::MailDeliveryJob for sending parameterized and normal mail. +# +# The default delivery jobs (ActionMailer::Parameterized::DeliveryJob, ActionMailer::DeliveryJob), +# will be removed in Rails 6.1. This setting is not backwards compatible with earlier Rails versions. +# If you send mail in the background, job workers need to have a copy of +# MailDeliveryJob to ensure all delivery jobs are processed properly. +# Make sure your entire app is migrated and stable on 6.0 before using this setting. +# Rails.application.config.action_mailer.delivery_job = "ActionMailer::MailDeliveryJob" + +# Enable the same cache key to be reused when the object being cached of type +# `ActiveRecord::Relation` changes by moving the volatile information (max updated at and count) +# of the relation's cache key into the cache version to support recycling cache key. +Rails.application.config.active_record.collection_cache_versioning = false diff --git a/config/initializers/pdfkit.rb b/config/initializers/pdfkit.rb deleted file mode 100644 index d7bbc64b8..000000000 --- a/config/initializers/pdfkit.rb +++ /dev/null @@ -1,12 +0,0 @@ -PDFKit.configure do |config| - installed = %x(which wkhtmltopdf).chomp - if installed == "" then - installed = "#{Rails.root}/vendor/bin/wkhtmltopdf" - end - config.wkhtmltopdf = installed - config.default_options = { - page_size: 'A4', - quiet: true - # :print_media_type => true - } -end diff --git a/config/initializers/que.rb b/config/initializers/que.rb new file mode 100644 index 000000000..560b1ec1e --- /dev/null +++ b/config/initializers/que.rb @@ -0,0 +1,7 @@ +Que::Adapters::Base::CAST_PROCS[1184] = lambda do |value| + case value + when Time then value + when String then Time.parse(value) + else raise "Unexpected time class: #{value.class} (#{value.inspect})" + end +end diff --git a/config/initializers/reload_api.rb b/config/initializers/reload_api.rb deleted file mode 100644 index 17e8bddc6..000000000 --- a/config/initializers/reload_api.rb +++ /dev/null @@ -1,11 +0,0 @@ -if Rails.env.development? - ActiveSupport::Dependencies.explicitly_unloadable_constants << 'Repp::API' - - api_files = Dir[Rails.root.join('app', 'api', '**', '*.rb')] - api_reloader = ActiveSupport::FileUpdateChecker.new(api_files) do - Rails.application.reload_routes! - end - ActionDispatch::Callbacks.to_prepare do - api_reloader.execute_if_updated - end -end diff --git a/config/initializers/truemail.rb b/config/initializers/truemail.rb new file mode 100644 index 000000000..f4517fbc0 --- /dev/null +++ b/config/initializers/truemail.rb @@ -0,0 +1,77 @@ +require 'truemail' + +Truemail.configure do |config| + # Required parameter. Must be an existing email on behalf of which verification will be performed + config.verifier_email = ENV['action_mailer_default_from'] + + # Optional parameter. Must be an existing domain on behalf of which verification will be performed. + # By default verifier domain based on verifier email + # config.verifier_domain = 'internet.ee' + + # Optional parameter. You can override default regex pattern + # config.email_pattern = /regex_pattern/ + + # Optional parameter. You can override default regex pattern + # config.smtp_error_body_pattern = /regex_pattern/ + + # Optional parameter. Connection timeout is equal to 2 ms by default. + # config.connection_timeout = 1 + + # Optional parameter. A SMTP server response timeout is equal to 2 ms by default. + # config.response_timeout = 1 + + # Optional parameter. Total of connection attempts. It is equal to 2 by default. + # This parameter uses in mx lookup timeout error and smtp request (for cases when + # there is one mx server). + config.connection_attempts = 3 + + # Optional parameter. You can predefine default validation type for + # Truemail.validate('email@email.com') call without with-parameter + # Available validation types: :regex, :mx, :smtp + if Rails.env.production? + config.default_validation_type = :mx + else + config.default_validation_type = :regex + end + + # Optional parameter. You can predefine which type of validation will be used for domains. + # Also you can skip validation by domain. Available validation types: :regex, :mx, :smtp + # This configuration will be used over current or default validation type parameter + # All of validations for 'somedomain.com' will be processed with regex validation only. + # And all of validations for 'otherdomain.com' will be processed with mx validation only. + # It is equal to empty hash by default. + # config.validation_type_for = { 'somedomain.com' => :regex, 'otherdomain.com' => :mx } + + # Optional parameter. Validation of email which contains whitelisted domain always will + # return true. Other validations will not processed even if it was defined in validation_type_for + # It is equal to empty array by default. + # config.whitelisted_domains = [] + + # Optional parameter. With this option Truemail will validate email which contains whitelisted + # domain only, i.e. if domain whitelisted, validation will passed to Regex, MX or SMTP validators. + # Validation of email which not contains whitelisted domain always will return false. + # It is equal false by default. + #config.whitelist_validation = true + + # Optional parameter. Validation of email which contains blacklisted domain always will + # return false. Other validations will not processed even if it was defined in validation_type_for + # It is equal to empty array by default. + #config.blacklisted_domains = [] + + # Optional parameter. This option will provide to use not RFC MX lookup flow. + # It means that MX and Null MX records will be cheked on the DNS validation layer only. + # By default this option is disabled. + # config.not_rfc_mx_lookup_flow = true + + # Optional parameter. This option will be parse bodies of SMTP errors. It will be helpful + # if SMTP server does not return an exact answer that the email does not exist + # By default this option is disabled, available for SMTP validation only. + # config.smtp_safe_check = true + + # Optional parameter. This option will enable tracking events. You can print tracking events to + # stdout, write to file or both of these. Tracking event by default is :error + # Available tracking event: :all, :unrecognized_error, :recognized_error, :error + unless Rails.env.test? + config.logger = { tracking_event: :all, stdout: true, log_absolute_path: Rails.root.join('log', 'truemail.log').to_s } + end +end diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb index 33725e95f..bbfc3961b 100644 --- a/config/initializers/wrap_parameters.rb +++ b/config/initializers/wrap_parameters.rb @@ -5,10 +5,10 @@ # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. ActiveSupport.on_load(:action_controller) do - wrap_parameters format: [:json] if respond_to?(:wrap_parameters) + wrap_parameters format: [:json] end # To enable root element in JSON for ActiveRecord objects. # ActiveSupport.on_load(:active_record) do -# self.include_root_in_json = true +# self.include_root_in_json = true # end diff --git a/config/locales/admin/account_activities.en.yml b/config/locales/admin/account_activities.en.yml index 2e91e7a8f..e7cc80d65 100644 --- a/config/locales/admin/account_activities.en.yml +++ b/config/locales/admin/account_activities.en.yml @@ -1,5 +1,6 @@ en: admin: account_activities: - index: + search_form: + download_btn: Download CSV reset_btn: Reset diff --git a/config/locales/admin/api_users.en.yml b/config/locales/admin/api_users.en.yml index 89a31f081..9fde2db14 100644 --- a/config/locales/admin/api_users.en.yml +++ b/config/locales/admin/api_users.en.yml @@ -2,16 +2,34 @@ en: admin: api_users: index: - new_btn: New API user - title: API users - active: Active - - show: - active: Active - subject: Subject + header: API users new: - title: New API user + header: New API user + + create: + created: API user has been successfully created + + show: + edit_btn: Edit + delete_btn: Delete + delete_btn_confirm: Are you sure you want to delete this API user? + + details: + header: Details + + certificates: + subject: Subject + + edit: + header: Edit API user + + update: + updated: API user has been successfully updated + + destroy: + deleted: API user has been successfully deleted form: - active: Active + create_btn: Create API user + update_btn: Update API user diff --git a/config/locales/admin/bank_statements.en.yml b/config/locales/admin/bank_statements.en.yml new file mode 100644 index 000000000..ca451e4f8 --- /dev/null +++ b/config/locales/admin/bank_statements.en.yml @@ -0,0 +1,5 @@ +en: + admin: + bank_statements: + index: + import_btn: Import \ No newline at end of file diff --git a/config/locales/admin/certificates.en.yml b/config/locales/admin/certificates.en.yml new file mode 100644 index 000000000..e2a774abd --- /dev/null +++ b/config/locales/admin/certificates.en.yml @@ -0,0 +1,5 @@ +en: + admin: + certificates: + new: + certificate_file: Certificate file \ No newline at end of file diff --git a/config/locales/admin/contacts.en.yml b/config/locales/admin/contacts.en.yml index 0ae48821f..44759886a 100644 --- a/config/locales/admin/contacts.en.yml +++ b/config/locales/admin/contacts.en.yml @@ -15,3 +15,6 @@ en: domains: roles: Roles + + statuses: + header: Statuses diff --git a/config/locales/admin/disputes.en.yml b/config/locales/admin/disputes.en.yml new file mode 100644 index 000000000..9632dde4a --- /dev/null +++ b/config/locales/admin/disputes.en.yml @@ -0,0 +1,19 @@ +en: + activerecord: + errors: + models: + dispute: + attributes: + starts_at: + future: 'can not be greater than today' + admin: + disputes: + index: + title: Disputed domains + new_btn: New disputed domain + reset_btn: Reset + + form: + password_hint: Generated automatically if left blank + optional: Not required by default + past_or_today: Can not be greater than today's date diff --git a/config/locales/admin/domains.en.yml b/config/locales/admin/domains.en.yml index 2abdaee91..c6e96bb15 100644 --- a/config/locales/admin/domains.en.yml +++ b/config/locales/admin/domains.en.yml @@ -31,6 +31,7 @@ en: force_delete_dialog: title: Force delete notify_by_email: Notify registrant and administrative contacts by email + use_soft_delete: Use soft delete procedure email_template: Email template close_btn: Close dialog submit_btn: Force delete domain diff --git a/config/locales/admin/email_verifable.en.yml b/config/locales/admin/email_verifable.en.yml new file mode 100644 index 000000000..724fa4c32 --- /dev/null +++ b/config/locales/admin/email_verifable.en.yml @@ -0,0 +1,5 @@ +en: + email_verifable: + email_smtp_check_error: SMTP check error + email_mx_check_error: Mail domain not found + email_regex_check_error: Invalid format diff --git a/config/locales/admin/email_verifable.et.yml b/config/locales/admin/email_verifable.et.yml new file mode 100644 index 000000000..6c008ed11 --- /dev/null +++ b/config/locales/admin/email_verifable.et.yml @@ -0,0 +1,5 @@ +et: + email_verifable: + email_smtp_check_error: Eposti aadressi ei leitud (SMTP viga) + email_mx_check_error: Eposti aadressi domeeni ei leitud + email_regex_check_error: Eposti aadress on vigane diff --git a/config/locales/admin/legal_documents.en.yml b/config/locales/admin/legal_documents.en.yml new file mode 100644 index 000000000..f24d883a6 --- /dev/null +++ b/config/locales/admin/legal_documents.en.yml @@ -0,0 +1,2 @@ +en: + legal_doc_not_found: "There is an error downloading legal document: file not found" diff --git a/config/locales/admin/legal_documents.et.yml b/config/locales/admin/legal_documents.et.yml new file mode 100644 index 000000000..d3ebfa512 --- /dev/null +++ b/config/locales/admin/legal_documents.et.yml @@ -0,0 +1,2 @@ +et: + legal_doc_not_found: "Viga juriidilise dokumendi allalaadimisel: faili ei leitud" diff --git a/config/locales/admin/menu.en.yml b/config/locales/admin/menu.en.yml index 2c31a5193..617341c6a 100644 --- a/config/locales/admin/menu.en.yml +++ b/config/locales/admin/menu.en.yml @@ -13,6 +13,7 @@ en: zones: Zones blocked_domains: Blocked domains reserved_domains: Reserved domains + disputed_domains: Disputed domains epp_log: EPP log repp_log: REPP log que: Que diff --git a/config/locales/admin/registrars.en.yml b/config/locales/admin/registrars.en.yml index 88e95843e..59a999bd2 100644 --- a/config/locales/admin/registrars.en.yml +++ b/config/locales/admin/registrars.en.yml @@ -25,7 +25,7 @@ en: preferences: header: Preferences - users: + api_users: header: API Users new_btn: New API user @@ -49,6 +49,8 @@ en: misc: Miscellaneous create_btn: Create registrar update_btn: Update registrar + legaldoc_optout: Opt-out from legal document requirement + legaldoc_optout_comment: Commentary on opt-out address: header: Address @@ -61,9 +63,10 @@ en: Applies to new invoices. Leave blank if a registrar is VAT-registered; registry's rate of %{registry_vat_rate} will be applied in this case. + billing_email_hint: Contact email will be used for billing purposes if left blank no_reference_number_hint: Reference number will be generated automatically disabled_reference_number_hint: Reference number cannot be changed iban_hint: Used for e-invoices preferences: - header: Preferences \ No newline at end of file + header: Preferences diff --git a/config/locales/api_users.en.yml b/config/locales/api_users.en.yml index 757ded049..9d4fcb63a 100644 --- a/config/locales/api_users.en.yml +++ b/config/locales/api_users.en.yml @@ -3,14 +3,4 @@ en: attributes: api_user: plain_text_password: Password - errors: - models: - api_user: - attributes: - username: - blank: 'Username is missing' - taken: 'Username already exists' - plain_text_password: - blank: 'Password is missing' - registrar: - blank: 'Registrar is missing' \ No newline at end of file + roles: Role diff --git a/config/locales/contacts.en.yml b/config/locales/contacts.en.yml index cdfe2277d..906bde193 100644 --- a/config/locales/contacts.en.yml +++ b/config/locales/contacts.en.yml @@ -20,6 +20,9 @@ en: email: blank: "Required parameter missing - email" invalid: "Email is invalid" + email_smtp_check_error: SMTP check error + email_mx_check_error: Mail domain not found + email_regex_check_error: Invalid format domains: exist: 'Object association prohibits operation' statuses: diff --git a/config/locales/en.yml b/config/locales/en.yml index 8beb4bed2..27299072e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,21 +1,4 @@ en: - views: - pagination: - first: "« First" - last: "Last »" - previous: "‹ Prev" - next: "Next ›" - truncate: "…" - helpers: - page_entries_info: - one_page: - display_entries: - zero: "No %{entry_name} found" - one: "Displaying 1 %{entry_name}" - other: "Displaying all %{count} %{entry_name}" - more_pages: - display_entries: "Displaying %{entry_name} %{first} - %{last} of %{total} in total" - time: formats: default: "%Y-%m-%d %H:%M" @@ -41,6 +24,8 @@ en: key_data_not_allowed: 'keyData object is not allowed' required_parameter_missing_reserved: 'Required parameter missing; reserved>pw element required for reserved domains' invalid_auth_information_reserved: 'Invalid authorization information; invalid reserved>pw value' + required_parameter_missing_disputed: 'Required parameter missing; disputed pw element required for dispute domains' + invalid_auth_information_disputed: 'Invalid authorization information; invalid disputed>pw value' domain_name_blocked: 'Data management policy violation: Domain name is blocked [name]' name_dirty: invalid: 'Domain name is invalid' @@ -150,22 +135,6 @@ en: taken: 'Public key already exists' blank: 'Public key is missing' - keyrelay: - attributes: - base: - only_one_parameter_allowed: 'Only one parameter allowed: %{param_1} or %{param_2}' - expiry_relative: - unknown_pattern: 'Expiry relative must be compatible to ISO 8601' - key_data_public_key: - blank: 'Public key is missing' - key_data_flags: - blank: 'Flag is missing' - key_data_protocol: - blank: 'Protocol is missing' - key_data_alg: - blank: 'Algorithm is missing' - auth_info_pw: - blank: 'Password is missing' legal_document: attributes: body: @@ -202,7 +171,6 @@ en: epp_domain_zone_with_same_origin: Zone with the same origin exists epp_domain_at_auction: Domain is at auction epp_domain_awaiting_payment: Awaiting payment - epp_obj_does_not_exist: 'Object does not exist' epp_authorization_error: 'Authorization error' epp_id_taken: 'Contact id already exists' epp_domain_not_found: 'Domain not found' @@ -229,7 +197,6 @@ en: domain_details: 'Domain details' registered_at: 'Registered at' password: 'Password' - authinfo_pw: 'AuthInfo pw' valid_from: 'Valid from' general: 'General' contacts: 'Contacts' @@ -241,6 +208,7 @@ en: statuses: 'Statuses' description: 'Description' delete: 'Delete' + remove_client_hold: 'Remove clientHold' are_you_sure: 'Are you sure?' back: 'Back' new_domain: 'New domain' @@ -311,7 +279,6 @@ en: certificate_signing_req: 'Certificate signing request' csr: 'CSR' crt: 'CRT' - back_to_api_user: 'Back to API user' dnskey: 'DNS key' dnskeys: 'DNS Keys' @@ -339,13 +306,11 @@ en: role: 'Role' user: 'User' customer_service: 'Customer service' - keyrelays: 'Keyrelays' uploaded_at: 'Uploaded at' expiry_relative: 'Expiry relative' expiry_absolute: 'Expiry absolute' requester: 'Requester' accepter: 'Accepter' - keyrelay_details: 'Keyrelay details' domain_name: 'Domain name' created_at: 'Created at' type: 'Type' @@ -366,7 +331,6 @@ en: request_method: 'Request method' response_code: 'Response code' request_params: 'Request params' - could_not_determine_object_type_check_xml_format_and_namespaces: 'Could not determine object type. Check XML format and namespaces.' unknown_expiry_relative_pattern: 'Expiry relative must be compatible to ISO 8601' unknown_expiry_absolute_pattern: 'Expiry absolute must be compatible to ISO 8601' mutally_exclusive_params: 'Mutually exclusive parameters: %{params}' @@ -457,7 +421,6 @@ en: exDate: 'Valid to' dequeue: 'Dequeue' are_you_sure_you_want_to_delete_domain: 'Are you sure you want to delete domain %{domain}?' - keyrelay: 'Keyrelay' upload_key: 'Upload key' legal_document: 'Legal document' legal_document_max_size: '(max. 8MB)' @@ -620,6 +583,7 @@ en: tech: Tech contact valid: Valid object_is_not_eligible_for_renewal: 'Object is not eligible for renewal' + object_is_not_holded: 'Object is not holded' bank_statement_desc: 'Import file row will match only when matching following attributes:
ref number
payment amount
invoice number (the first numerical value in comment field)
.' create_bank_statement: 'Create bank statement' create_bank_transaction: 'Create bank transaction' @@ -630,7 +594,6 @@ en: receipt_date_from: 'Receipt date from' receipt_date_until: 'Receipt date until' add_credit: 'Add credit' - export_csv: 'Export CSV' invalid_yaml: 'Invalid YAML' reserved_pw: 'Reserved pw' no_transfers_found: 'No transfers found' @@ -659,16 +622,21 @@ en: created_at_from: 'Created at from' created_at_until: 'Created at until' is_registrant: 'Is registrant' - force_delete_set_on_domain: 'Force delete set on domain %{domain_name}' + force_delete_set_on_domain: 'Force delete set on domain %{domain_name}. Outzone date: %{outzone_date}. Purge date: %{purge_date}' + grace_period_started_domain: 'For domain %{domain_name} started 45-days redemption grace period, ForceDelete will be in effect from %{date}' + force_delete_cancelled: 'Force delete is cancelled on domain %{domain_name}' contact_is_not_valid: 'Contact %{value} is not valid, please fix the invalid contact' next: 'Next' previous: 'Previous' available_verification_url_not_found: 'Available verification url not found, for domain.' add_reserved_domain: 'Add domain to reserved list' add_blocked_domain: 'Add domain to blocked list' + add_disputed_domain: 'Add domain to disputed list' edit_pw: 'Edit Pw' + edit_dispute: 'Edit dispute' optional: 'Optional' test_registrar: "Test registrar" + emails: 'Email addresses' verified_confirm: 'Verified status is for cases when current registrant is the one applying for the update. Legal document signed by the registrant is required. Are you sure this update is properly verified with the registrant?' verified: 'Verified' deleted: 'Deleted' diff --git a/config/locales/et.yml b/config/locales/et.yml index 05d32be24..9cb8aaa4a 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -5,3 +5,4 @@ et: date: # Don't forget the nil at the beginning; there's no such thing as a 0th month month_names: [~, Jaanuar, Veebruar, Märts, Aprill, Mai, Juuni, Juuli, August, September, Oktoober, November, Detsember] + emails: "Meillaadressid" diff --git a/config/locales/registrant/domains.en.yml b/config/locales/registrant/domains.en.yml index 2dbdce79a..1e02d00e1 100644 --- a/config/locales/registrant/domains.en.yml +++ b/config/locales/registrant/domains.en.yml @@ -4,11 +4,10 @@ en: index: header: Domains registrant: Registrant + download_pdf_btn: Download PDF + download_csv_btn: Download CSV reset_btn: Reset - download_list: - registrant: Registrant - partials: registrant: header: Registrant diff --git a/config/locales/registrar/account_activities.en.yml b/config/locales/registrar/account_activities.en.yml index 27d0150d6..374760065 100644 --- a/config/locales/registrar/account_activities.en.yml +++ b/config/locales/registrar/account_activities.en.yml @@ -1,5 +1,6 @@ en: registrar: account_activities: - index: + search_form: + download_btn: Download CSV reset_btn: Reset diff --git a/config/locales/registrar/contacts.en.yml b/config/locales/registrar/contacts.en.yml index 84afd481d..590e419d2 100644 --- a/config/locales/registrar/contacts.en.yml +++ b/config/locales/registrar/contacts.en.yml @@ -1,7 +1,9 @@ en: registrar: contacts: - index: + search_form: + download_pdf_btn: Download PDF + download_csv_btn: Download CSV reset_btn: Reset partials: diff --git a/config/locales/registrar/domains.en.yml b/config/locales/registrar/domains.en.yml index 31380074f..c98002b8f 100644 --- a/config/locales/registrar/domains.en.yml +++ b/config/locales/registrar/domains.en.yml @@ -17,7 +17,7 @@ en: transfer_btn: Transfer search_form: - download_btn: Download as CSV + download_btn: Download CSV reset_btn: Reset domain: diff --git a/config/locales/registrar/payments.en.yml b/config/locales/registrar/payments.en.yml new file mode 100644 index 000000000..9c817e0ea --- /dev/null +++ b/config/locales/registrar/payments.en.yml @@ -0,0 +1,7 @@ +en: + registrar: + payments: + back: + payment_successful: 'Thank you! Payment received successfully.' + successful_payment_backend_error: 'We received your payment, but something went wrong on our side. Please contact us via email or phone.' + payment_not_received: 'Payment was unsuccessful. Please make sure you have enough funds on your account and try again.' diff --git a/config/locales/registrars.en.yml b/config/locales/registrars.en.yml index 609f9f94a..c57f2e891 100644 --- a/config/locales/registrars.en.yml +++ b/config/locales/registrars.en.yml @@ -1,4 +1,8 @@ en: + registrar: + invoice_yearly_product_description: '%{tld} registration: %{length} year(s)' + invoice_monthly_product_description: '%{tld} registration: %{length} month(s)' + monthly_summary_title: 'Domain registrations - %{date}' activerecord: errors: models: @@ -8,4 +12,4 @@ en: forbidden: is forbidden vat_rate: present: >- - must be blank when a registrar is VAT-registered in the same country as registry \ No newline at end of file + must be blank when a registrar is VAT-registered in the same country as registry diff --git a/config/locales/registrars.et.yml b/config/locales/registrars.et.yml new file mode 100644 index 000000000..1001638c1 --- /dev/null +++ b/config/locales/registrars.et.yml @@ -0,0 +1,5 @@ +et: + registrar: + invoice_yearly_product_description: '%{tld} registreerimine: %{length} aasta(t)' + invoice_monthly_product_description: '%{tld} registreerimine: %{length} kuu(d)' + monthly_summary_title: 'Domeenide registreerimine - %{date}' diff --git a/config/routes.rb b/config/routes.rb index ab72d0092..1c03129db 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,23 +1,57 @@ require_dependency 'epp_constraint' Rails.application.routes.draw do - namespace(:epp, defaults: { format: :xml }) do - match 'session/:action', controller: 'sessions', via: :all, constraints: EppConstraint.new(:session) - match 'session/pki/:action', controller: 'sessions', via: :all, constraints: EppConstraint.new(:session) + # https://github.com/internetee/epp_proxy#translation-of-epp-calls + namespace :epp do + constraints(EppConstraint.new(:session)) do + get 'session/hello', to: 'sessions#hello', as: 'hello' + post 'session/login', to: 'sessions#login', as: 'login' + post 'session/logout', to: 'sessions#logout', as: 'logout' + end - post 'command/:action', controller: 'domains', constraints: EppConstraint.new(:domain) - post 'command/:action', controller: 'contacts', constraints: EppConstraint.new(:contact) - post 'command/poll', to: 'polls#poll', constraints: EppConstraint.new(:poll) - post 'command/keyrelay', to: 'keyrelays#keyrelay', constraints: EppConstraint.new(:keyrelay) + constraints(EppConstraint.new(:contact)) do + controller('contacts') do + post 'command/create', action: 'create', as: :create + post 'command/update', action: 'update', as: :update + post 'command/info', action: 'info', as: :info + post 'command/check', action: 'check', as: :check + post 'command/transfer', action: 'transfer', as: :transfer + post 'command/renew', action: 'renew', as: :renew + post 'command/delete', action: 'delete', as: :delete + end + end - post 'command/:command', to: 'errors#not_found', constraints: EppConstraint.new(:not_found) # fallback route + constraints(EppConstraint.new(:domain)) do + controller('domains') do + post 'command/create', action: 'create', as: nil + post 'command/update', action: 'update', as: nil + post 'command/info', action: 'info', as: nil + post 'command/check', action: 'check', as: nil + post 'command/transfer', action: 'transfer', as: nil + post 'command/renew', action: 'renew', as: nil + post 'command/delete', action: 'delete', as: nil + end + end + post 'command/poll', to: 'polls#poll', as: 'poll', constraints: EppConstraint.new(:poll) get 'error/:command', to: 'errors#error' - match "*command", to: 'errors#error', via: [:post, :get, :patch, :put, :delete] end mount Repp::API => '/' + namespace :repp do + namespace :v1 do + resources :auctions, only: %i[index] + resources :retained_domains, only: %i[index] + end + end + + match 'repp/v1/*all', + controller: 'api/cors', + action: 'cors_preflight_check', + via: [:options], + as: 'repp_cors_preflight_check' + namespace :api do namespace :v1 do namespace :registrant do @@ -78,6 +112,7 @@ Rails.application.routes.draw do get 'check' get 'delete' get 'search_contacts' + get 'remove_hold' end end resources :domain_transfers, only: %i[new create] @@ -91,30 +126,26 @@ Rails.application.routes.draw do collection do get 'check' - get 'download_list' end end resource :poll, only: %i[show destroy] do collection do - post 'confirm_keyrelay' post 'confirm_transfer' end end - resource :keyrelay - resource :xml_console do collection do get 'load_xml' end end - get 'pay/return/:bank' => 'payments#back', as: 'return_payment_with' - post 'pay/return/:bank' => 'payments#back' - put 'pay/return/:bank' => 'payments#back' - post 'pay/callback/:bank' => 'payments#callback', as: 'response_payment_with' - get 'pay/go/:bank' => 'payments#pay', as: 'payment_with' + get 'pay/return/:payment_order' => 'payments#back', as: 'return_payment_with' + post 'pay/return/:payment_order' => 'payments#back' + put 'pay/return/:payment_order' => 'payments#back' + post 'pay/callback/:payment_order' => 'payments#callback', as: 'response_payment_with' + get 'pay/go/:bank' => 'payments#pay', as: 'payment_with' namespace :settings do resource :balance_auto_reload, controller: :balance_auto_reload, only: %i[edit update destroy] @@ -155,11 +186,6 @@ Rails.application.routes.draw do resources :registrars, only: :show resources :domains, only: %i[index show] do resources :contacts, only: %i[show edit update] - - collection do - get :download_list - end - member do get 'confirmation' end @@ -174,12 +200,9 @@ Rails.application.routes.draw do root 'dashboard#show' devise_for :users, path: '', class_name: 'AdminUser' - resources :keyrelays resources :zonefiles resources :zones, controller: 'dns/zones', except: %i[show destroy] resources :legal_documents - resources :keyrelays - resources :prices, controller: 'billing/prices', except: %i[show destroy] do member do patch :expire @@ -248,13 +271,16 @@ Rails.application.routes.draw do get 'delete' end end - - resources :registrars do - resources :api_users - resources :white_ips + resources :disputes do + member do + get 'delete' + end end - resources :registrants, controller: 'contacts' + resources :registrars do + resources :api_users, except: %i[index] + resources :white_ips + end resources :contacts do collection do @@ -263,7 +289,8 @@ Rails.application.routes.draw do end resources :admin_users - resources :api_users do + # /admin/api_users is mainly for manual testing + resources :api_users, only: [:index, :show] do resources :certificates do member do post 'sign' diff --git a/config/schedule.rb b/config/schedule.rb index 88bf48c61..0106cc97d 100644 --- a/config/schedule.rb +++ b/config/schedule.rb @@ -46,6 +46,10 @@ if @cron_group == 'registry' runner 'DomainCron.start_redemption_grace_period' end + every 1.day do + runner 'DomainCron.start_client_hold' + end + every '0 0 1 * *' do runner 'Directo.send_monthly_invoices' end @@ -57,6 +61,17 @@ if @cron_group == 'registry' every 42.minutes do rake 'domain:discard' end + + every 10.minutes do + rake 'verify_email:all_domains' + end + + # Should be at least once every 4 days, since according to LHV specs: + # "Unread messages older than 5 days are automatically scheduled for deletion" + # https://partners.lhv.ee/en/connect/#messaging + every :day, at: '12:01am' do + rake 'invoices:process_payments' + end end every 10.minutes do diff --git a/config/secrets.yml b/config/secrets.yml new file mode 100644 index 000000000..5a3114b22 --- /dev/null +++ b/config/secrets.yml @@ -0,0 +1,22 @@ +# Be sure to restart your server when you modify this file. + +# Your secret key is used for verifying the integrity of signed cookies. +# If you change this key, all old signed cookies will become invalid! + +# Make sure the secret is at least 30 characters and all random, +# no regular words or you'll be exposed to dictionary attacks. +# You can use `rails secret` to generate a secure secret key. + +# Make sure the secrets in this file are kept private +# if you're sharing your code publicly. + +development: + secret_key_base: d876b4cf172fe17628b4486b302e1d805109f4dfbf25aa8f2d89e6cf821dfdc94f4c753e4fdbaa0b6647ba687058266661632b2cd3975c41fb21dbc588b38c92 + +test: + secret_key_base: 69ecc590b3de231130e3fb390df48a4eb9259722754ef5df6a9e9ab78d69149d8c16ec2d79791c5ba7a89ad7c5afaa8cec1aa794e9a6f986d3c7319a08d6bce2 + +# Do not keep production secrets in the repository, +# instead read values from the environment. +production: + secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> diff --git a/config/spring.rb b/config/spring.rb new file mode 100644 index 000000000..c9119b40c --- /dev/null +++ b/config/spring.rb @@ -0,0 +1,6 @@ +%w( + .ruby-version + .rbenv-vars + tmp/restart.txt + tmp/caching-dev.txt +).each { |path| Spring.watch(path) } diff --git a/config/storage.yml b/config/storage.yml new file mode 100644 index 000000000..d32f76e8f --- /dev/null +++ b/config/storage.yml @@ -0,0 +1,34 @@ +test: + service: Disk + root: <%= Rails.root.join("tmp/storage") %> + +local: + service: Disk + root: <%= Rails.root.join("storage") %> + +# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) +# amazon: +# service: S3 +# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> +# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> +# region: us-east-1 +# bucket: your_own_bucket + +# Remember not to checkin your GCS keyfile to a repository +# google: +# service: GCS +# project: your_project +# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> +# bucket: your_own_bucket + +# Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) +# microsoft: +# service: AzureStorage +# storage_account_name: your_account_name +# storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> +# container: your_container_name + +# mirror: +# service: Mirror +# primary: local +# mirrors: [ amazon, google, microsoft ] diff --git a/db/data/20150601083516_add_cert_common_name.rb b/db/data/20150601083516_add_cert_common_name.rb index ef401b871..d0959e5b7 100644 --- a/db/data/20150601083516_add_cert_common_name.rb +++ b/db/data/20150601083516_add_cert_common_name.rb @@ -1,16 +1,15 @@ -class AddCertCommonName < ActiveRecord::Migration +class AddCertCommonName < ActiveRecord::Migration[5.1] def self.up - Certificate.all.each do |x| - if x.crt.blank? && x.csr.present? - pc = x.parsed_csr.try(:subject).try(:to_s) || '' - cn = pc.scan(/\/CN=(.+)/).flatten.first - x.common_name = cn.split('/').first - end - x.save - end + # Certificate.all.each do |x| + # if x.crt.blank? && x.csr.present? + # pc = x.parsed_csr.try(:subject).try(:to_s) || '' + # cn = pc.scan(/\/CN=(.+)/).flatten.first + # x.common_name = cn.split('/').first + # end + # x.save + # end end def self.down - raise ActiveRecord::IrreversibleMigration end end diff --git a/db/data/20150601083800_add_cert_md5.rb b/db/data/20150601083800_add_cert_md5.rb index 5efe4e596..4db005177 100644 --- a/db/data/20150601083800_add_cert_md5.rb +++ b/db/data/20150601083800_add_cert_md5.rb @@ -1,28 +1,27 @@ -class AddCertMd5 < ActiveRecord::Migration +class AddCertMd5 < ActiveRecord::Migration[5.1] def self.up - Certificate.all.each do |x| - if x.crt.present? && x.csr.present? - x.interface = Certificate::REGISTRAR - x.md5 = OpenSSL::Digest::MD5.new(x.parsed_crt.to_der).to_s - - pc = x.parsed_crt.try(:subject).try(:to_s) || '' - cn = pc.scan(/\/CN=(.+)/).flatten.first - x.common_name = cn.split('/').first - elsif x.crt.present? && x.csr.blank? - x.interface = Certificate::API - x.md5 = OpenSSL::Digest::MD5.new(x.parsed_crt.to_der).to_s - - pc = x.parsed_crt.try(:subject).try(:to_s) || '' - cn = pc.scan(/\/CN=(.+)/).flatten.first - x.common_name = cn.split('/').first - elsif x.crt.blank? && x.csr.present? - x.interface = Certificate::REGISTRAR - end - x.save - end + # Certificate.all.each do |x| + # if x.crt.present? && x.csr.present? + # x.interface = Certificate::REGISTRAR + # x.md5 = OpenSSL::Digest::MD5.new(x.parsed_crt.to_der).to_s + # + # pc = x.parsed_crt.try(:subject).try(:to_s) || '' + # cn = pc.scan(/\/CN=(.+)/).flatten.first + # x.common_name = cn.split('/').first + # elsif x.crt.present? && x.csr.blank? + # x.interface = Certificate::API + # x.md5 = OpenSSL::Digest::MD5.new(x.parsed_crt.to_der).to_s + # + # pc = x.parsed_crt.try(:subject).try(:to_s) || '' + # cn = pc.scan(/\/CN=(.+)/).flatten.first + # x.common_name = cn.split('/').first + # elsif x.crt.blank? && x.csr.present? + # x.interface = Certificate::REGISTRAR + # end + # x.save + # end end def self.down - raise ActiveRecord::IrreversibleMigration end end diff --git a/db/data/20150609093515_add_renew_setting.rb b/db/data/20150609093515_add_renew_setting.rb index f462c38cb..2d99aa448 100644 --- a/db/data/20150609093515_add_renew_setting.rb +++ b/db/data/20150609093515_add_renew_setting.rb @@ -1,9 +1,8 @@ -class AddRenewSetting < ActiveRecord::Migration +class AddRenewSetting < ActiveRecord::Migration[5.1] def self.up - Setting.days_to_renew_domain_before_expire = 90 + # Setting.days_to_renew_domain_before_expire = 90 end def self.down - raise ActiveRecord::IrreversibleMigration end end diff --git a/db/data/20150610111019_add_expire_settings.rb b/db/data/20150610111019_add_expire_settings.rb index 9f8b9cce8..6171536dd 100644 --- a/db/data/20150610111019_add_expire_settings.rb +++ b/db/data/20150610111019_add_expire_settings.rb @@ -1,10 +1,9 @@ -class AddExpireSettings < ActiveRecord::Migration +class AddExpireSettings < ActiveRecord::Migration[5.1] def self.up - Setting.expire_warning_period = 15 - Setting.redemption_grace_period = 30 + # Setting.expire_warning_period = 15 + # Setting.redemption_grace_period = 30 end def self.down - raise ActiveRecord::IrreversibleMigration end end diff --git a/db/data/20150612125720_refactor_domain_statuses.rb b/db/data/20150612125720_refactor_domain_statuses.rb index 00e87b4d0..de0733e3f 100644 --- a/db/data/20150612125720_refactor_domain_statuses.rb +++ b/db/data/20150612125720_refactor_domain_statuses.rb @@ -1,15 +1,14 @@ -class RefactorDomainStatuses < ActiveRecord::Migration +class RefactorDomainStatuses < ActiveRecord::Migration[5.1] def self.up - Domain.find_each do |x| - statuses = [] - x.domain_statuses.each do |ds| - statuses << ds.value - end - x.update_column('statuses', statuses) - end + # Domain.find_each do |x| + # statuses = [] + # x.domain_statuses.each do |ds| + # statuses << ds.value + # end + # x.update_column('statuses', statuses) if x.statuses.blank? + # end end def self.down - raise ActiveRecord::IrreversibleMigration end end diff --git a/db/data/20150707103801_refactor_contact_statuses.rb b/db/data/20150707103801_refactor_contact_statuses.rb index be6312016..e1833dd66 100644 --- a/db/data/20150707103801_refactor_contact_statuses.rb +++ b/db/data/20150707103801_refactor_contact_statuses.rb @@ -1,15 +1,14 @@ -class RefactorContactStatuses < ActiveRecord::Migration +class RefactorContactStatuses < ActiveRecord::Migration[5.1] def self.up - Contact.find_each do |contact| - statuses = [] - contact.depricated_statuses.each do |ds| - statuses << ds.value - end - contact.update_column('statuses', statuses) - end + # Contact.find_each do |contact| + # statuses = [] + # contact.depricated_statuses.each do |ds| + # statuses << ds.value + # end + # contact.update_column('statuses', statuses) + # end end def self.down - raise ActiveRecord::IrreversibleMigration end end diff --git a/db/data/20200225085234_convert_domain_delete_date.rb b/db/data/20200225085234_convert_domain_delete_date.rb new file mode 100644 index 000000000..81f070927 --- /dev/null +++ b/db/data/20200225085234_convert_domain_delete_date.rb @@ -0,0 +1,19 @@ +class ConvertDomainDeleteDate < ActiveRecord::Migration[5.1] + def up + # processed_domain_count = 0 + # + # Domain.transaction do + # Domain.find_each do |domain| + # next unless domain.delete_date + # + # domain.update_columns(delete_date: domain.delete_date + 1.day) + # processed_domain_count += 1 + # end + # end + # + # puts "Domains processed: #{processed_domain_count}" + end + + def down + end +end diff --git a/db/data/20200225085433_delete_orphaned_registrant_verifications.rb b/db/data/20200225085433_delete_orphaned_registrant_verifications.rb new file mode 100644 index 000000000..73c270a6a --- /dev/null +++ b/db/data/20200225085433_delete_orphaned_registrant_verifications.rb @@ -0,0 +1,18 @@ +class DeleteOrphanedRegistrantVerifications < ActiveRecord::Migration[5.1] + def up + # orphaned_registrant_verifications = RegistrantVerification.where.not(domain_id: Domain.ids) + # orphaned_registrant_verification_count = orphaned_registrant_verifications.count + # processed_registrant_verification_count = 0 + # + # orphaned_registrant_verifications.each do |registrant_verification| + # registrant_verification.destroy! + # processed_registrant_verification_count += 1 + # end + # + # puts "Processed: #{processed_registrant_verification_count} out of" \ + # " #{orphaned_registrant_verification_count}" + end + + def down + end +end diff --git a/db/data/20200225085539_regenerate_registrar_reference_numbers.rb b/db/data/20200225085539_regenerate_registrar_reference_numbers.rb new file mode 100644 index 000000000..fbd2a5c5f --- /dev/null +++ b/db/data/20200225085539_regenerate_registrar_reference_numbers.rb @@ -0,0 +1,19 @@ +class RegenerateRegistrarReferenceNumbers < ActiveRecord::Migration[5.1] + def up + # processed_registrar_count = 0 + # + # Registrar.transaction do + # Registrar.all.each do |registrar| + # next unless registrar.reference_no.start_with?('RF') + # + # registrar.update_columns(reference_no: Billing::ReferenceNo.generate) + # processed_registrar_count += 1 + # end + # end + # + # puts "Registrars processed: #{processed_registrar_count}" + end + + def down + end +end diff --git a/db/data/20200608084321_fill_email_verifications.rb b/db/data/20200608084321_fill_email_verifications.rb new file mode 100644 index 000000000..f1186983e --- /dev/null +++ b/db/data/20200608084321_fill_email_verifications.rb @@ -0,0 +1,21 @@ +class FillEmailVerifications < ActiveRecord::Migration[6.0] + include Concerns::EmailVerifable + + def up + # registrar_billing_emails = Registrar.pluck(:billing_email).uniq.reject(&:blank?) + # registrar_emails = Registrar.pluck(:email).uniq.reject(&:blank?) + # contact_emails = Contact.pluck(:email).uniq.reject(&:blank?) + # + # emails = (contact_emails + registrar_emails + registrar_billing_emails) + # emails = emails.map{ |email| punycode_to_unicode(email) }.uniq + # + # result = emails.map do |email| + # { email: email, domain: domain(email) } + # end + # EmailAddressVerification.import result, batch_size: 500 + end + + def down + EmailAddressVerification.delete_all + end +end diff --git a/db/data/20200702074549_fill_single_characted_blocked_domains.rb b/db/data/20200702074549_fill_single_characted_blocked_domains.rb new file mode 100644 index 000000000..da8bac9be --- /dev/null +++ b/db/data/20200702074549_fill_single_characted_blocked_domains.rb @@ -0,0 +1,20 @@ +class FillSingleCharactedBlockedDomains < ActiveRecord::Migration[6.0] + + DOMAIN_NAMES = %w[a.ee b.ee c.ee d.ee e.ee f.ee g.ee h.ee i.ee j.ee k.ee l.ee m.ee n.ee o.ee + p.ee q.ee r.ee s.ee š.ee z.ee ž.ee t.ee u.ee v.ee w.ee õ.ee ä.ee ö.ee ü.ee + x.ee y.ee 0.ee 1.ee 2.ee 3.ee 4.ee 5.ee 6.ee 7.ee 8.ee 9.ee].freeze + + def up + BlockedDomain.transaction do + DOMAIN_NAMES.each do |name| + BlockedDomain.find_or_create_by(name: name) + end + end + end + + def down + BlockedDomain.transaction do + BlockedDomain.by_domain(DOMAIN_NAMES).delete_all + end + end +end diff --git a/db/data/20200702104334_add_legal_document_mandatory_setting.rb b/db/data/20200702104334_add_legal_document_mandatory_setting.rb new file mode 100644 index 000000000..9e3bf40fc --- /dev/null +++ b/db/data/20200702104334_add_legal_document_mandatory_setting.rb @@ -0,0 +1,11 @@ +class AddLegalDocumentMandatorySetting < ActiveRecord::Migration[6.0] + def up + Setting.create(code: 'legal_document_is_mandatory', + value: 'true', format: 'boolean', + group: 'domain_validation') + end + + def down + Setting.find_by(code: 'legal_document_is_mandatory').destroy + end +end diff --git a/db/data/20200812093540_copy_legacy_settings_to_new_model.rb b/db/data/20200812093540_copy_legacy_settings_to_new_model.rb new file mode 100644 index 000000000..bb762aa21 --- /dev/null +++ b/db/data/20200812093540_copy_legacy_settings_to_new_model.rb @@ -0,0 +1,87 @@ +class CopyLegacySettingsToNewModel < ActiveRecord::Migration[6.0] + def up + validation_group = + %w[admin_contacts_min_count admin_contacts_max_count tech_contacts_min_count ns_min_count + tech_contacts_max_count orphans_contacts_in_months key_data_allowed dnskeys_min_count + dnskeys_max_count nameserver_required expire_pending_confirmation ds_data_allowed + legal_document_is_mandatory ns_max_count].freeze + + expiration_group = + %w[days_to_renew_domain_before_expire expire_warning_period redemption_grace_period + expiration_reminder_mail].freeze + + billing_group = + %w[invoice_number_min invoice_number_max directo_monthly_number_min + directo_monthly_number_last days_to_keep_invoices_active directo_monthly_number_max + days_to_keep_overdue_invoices_active minimum_deposit directo_receipt_payment_term + directo_receipt_product_name directo_sales_agent registry_billing_email + registry_invoice_contact registry_vat_no registry_vat_prc registry_bank + registry_iban registry_swift directo_monthly_number_max registry_bank_code].freeze + + contacts_group = + %w[registry_juridical_name registry_reg_no registry_email registry_phone registry_url + registry_street registry_city registry_state registry_zip registry_country_code + registry_whois_disclaimer].freeze + + integer_vars = + %w[admin_contacts_min_count admin_contacts_max_count tech_contacts_min_count + tech_contacts_max_count orphans_contacts_in_months ds_digest_type dnskeys_min_count + dnskeys_max_count ns_min_count ns_max_count transfer_wait_time invoice_number_min + invoice_number_max days_to_keep_invoices_active days_to_keep_overdue_invoices_active + days_to_renew_domain_before_expire expire_warning_period redemption_grace_period + expire_pending_confirmation dispute_period_in_months].freeze + + float_vars = %w[registry_vat_prc minimum_deposit].freeze + + boolean_vars = + %w[ + ds_data_allowed + key_data_allowed + client_side_status_editing_enabled + registrar_ip_whitelist_enabled + api_ip_whitelist_enabled + request_confrimation_on_registrant_change_enabled + request_confirmation_on_domain_deletion_enabled + nameserver_required + address_processing + legal_document_is_mandatory + ].freeze + + sql = 'SELECT var, value, created_at, updated_at, creator_str, updator_str FROM' \ + ' settings ORDER BY settings.id ASC' + old_settings = ActiveRecord::Base.connection.execute(sql) + + old_settings.each do |origin| + next if origin['var'] == 'days_to_keep_business_registry_cache' + entry = SettingEntry.find_or_initialize_by(code: origin['var']) + entry[:format] = 'string' + entry[:format] = 'boolean' if boolean_vars.include? entry.code + entry[:format] = 'float' if float_vars.include? entry.code + entry[:format] = 'integer' if integer_vars.include? entry.code + + entry[:group] = 'other' + entry[:group] = 'domain_validation' if validation_group.include? entry.code + entry[:group] = 'domain_expiration' if expiration_group.include? entry.code + entry[:group] = 'billing' if billing_group.include? entry.code + entry[:group] = 'contacts' if contacts_group.include? entry.code + + %w[value created_at updated_at creator_str updator_str].each do |field| + entry[field] = origin[field] + next if field != 'value' + + entry.value = origin[field].gsub('--- ', '').strip.gsub("'", '') + end + + if entry.save + logger.info "Legacy setting '#{entry.code}' successfully migrated to SettingEntry" + else + logger.error "!!! Failed to migrate setting '#{entry.code}': " \ + "#{entry.errors.full_messages.join(', ')}" + end + end + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end diff --git a/db/data/20200901131427_remove_unused_setting_entries.rb b/db/data/20200901131427_remove_unused_setting_entries.rb new file mode 100644 index 000000000..d2bb11317 --- /dev/null +++ b/db/data/20200901131427_remove_unused_setting_entries.rb @@ -0,0 +1,15 @@ +class RemoveUnusedSettingEntries < ActiveRecord::Migration[6.0] + def up + unused_fields = %w[eis_iban eis_bank eis_swift eis_invoice_contact ds_data_with_key_allowed] + unused_fields.each do |stg| + setting = SettingEntry.find_by(code: stg) + next unless setting + + setting.destroy + end + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end diff --git a/db/data_schema.rb b/db/data_schema.rb new file mode 100644 index 000000000..2968b1184 --- /dev/null +++ b/db/data_schema.rb @@ -0,0 +1,2 @@ +# encoding: UTF-8 +DataMigrate::Data.define(version: 20200901131427) diff --git a/db/migrate/20180801114403_change_contacts_name_to_not_null.rb b/db/migrate/20180801114403_change_contacts_name_to_not_null.rb new file mode 100644 index 000000000..cfa4064ba --- /dev/null +++ b/db/migrate/20180801114403_change_contacts_name_to_not_null.rb @@ -0,0 +1,5 @@ +class ChangeContactsNameToNotNull < ActiveRecord::Migration + def change + change_column_null :contacts, :name, false + end +end \ No newline at end of file diff --git a/db/migrate/20190811184334_remove_invoices_seller_id.rb b/db/migrate/20190811184334_remove_invoices_seller_id.rb new file mode 100644 index 000000000..d96dfedb4 --- /dev/null +++ b/db/migrate/20190811184334_remove_invoices_seller_id.rb @@ -0,0 +1,5 @@ +class RemoveInvoicesSellerId < ActiveRecord::Migration + def change + remove_column :invoices, :seller_id + end +end diff --git a/db/migrate/20190811195814_change_invoices_number_to_not_null.rb b/db/migrate/20190811195814_change_invoices_number_to_not_null.rb new file mode 100644 index 000000000..122e27572 --- /dev/null +++ b/db/migrate/20190811195814_change_invoices_number_to_not_null.rb @@ -0,0 +1,5 @@ +class ChangeInvoicesNumberToNotNull < ActiveRecord::Migration + def change + change_column_null :invoices, :number, false + end +end diff --git a/db/migrate/20190811202042_add_invoices_number_uniq_constraint.rb b/db/migrate/20190811202042_add_invoices_number_uniq_constraint.rb new file mode 100644 index 000000000..423214355 --- /dev/null +++ b/db/migrate/20190811202042_add_invoices_number_uniq_constraint.rb @@ -0,0 +1,13 @@ +class AddInvoicesNumberUniqConstraint < ActiveRecord::Migration + def up + execute <<-SQL + ALTER TABLE invoices ADD CONSTRAINT unique_number UNIQUE (number) + SQL + end + + def down + execute <<-SQL + ALTER TABLE invoices DROP CONSTRAINT unique_number + SQL + end +end diff --git a/db/migrate/20190811202347_add_invoices_buyer_id_fk.rb b/db/migrate/20190811202347_add_invoices_buyer_id_fk.rb new file mode 100644 index 000000000..de2a82fcd --- /dev/null +++ b/db/migrate/20190811202347_add_invoices_buyer_id_fk.rb @@ -0,0 +1,5 @@ +class AddInvoicesBuyerIdFk < ActiveRecord::Migration + def change + add_foreign_key :invoices, :registrars, column: :buyer_id + end +end diff --git a/db/migrate/20190811202711_change_invoices_required_columns_to_not_null.rb b/db/migrate/20190811202711_change_invoices_required_columns_to_not_null.rb new file mode 100644 index 000000000..fc8f0f895 --- /dev/null +++ b/db/migrate/20190811202711_change_invoices_required_columns_to_not_null.rb @@ -0,0 +1,15 @@ +class ChangeInvoicesRequiredColumnsToNotNull < ActiveRecord::Migration + def change + change_column_null :invoices, :buyer_id, false + change_column_null :invoices, :seller_reg_no, false + change_column_null :invoices, :seller_bank, false + change_column_null :invoices, :seller_swift, false + change_column_null :invoices, :seller_country_code, false + change_column_null :invoices, :seller_street, false + change_column_null :invoices, :seller_city, false + change_column_null :invoices, :buyer_reg_no, false + change_column_null :invoices, :buyer_country_code, false + change_column_null :invoices, :buyer_street, false + change_column_null :invoices, :buyer_city, false + end +end diff --git a/db/migrate/20190811205406_change_invoices_required_columns_to_not_null_part2.rb b/db/migrate/20190811205406_change_invoices_required_columns_to_not_null_part2.rb new file mode 100644 index 000000000..57e9d7d9b --- /dev/null +++ b/db/migrate/20190811205406_change_invoices_required_columns_to_not_null_part2.rb @@ -0,0 +1,7 @@ +class ChangeInvoicesRequiredColumnsToNotNullPart2 < ActiveRecord::Migration + def change + change_column_null :invoices, :seller_email, false + change_column_null :invoices, :seller_contact_name, false + change_column_null :invoices, :buyer_email, false + end +end diff --git a/db/migrate/20190917114907_drop_keyrelays.rb b/db/migrate/20190917114907_drop_keyrelays.rb new file mode 100644 index 000000000..cfe69ae9d --- /dev/null +++ b/db/migrate/20190917114907_drop_keyrelays.rb @@ -0,0 +1,6 @@ +class DropKeyrelays < ActiveRecord::Migration + def change + drop_table :keyrelays + drop_table :log_keyrelays + end +end diff --git a/db/migrate/20191004095229_change_reserved_domains_name_to_not_null.rb b/db/migrate/20191004095229_change_reserved_domains_name_to_not_null.rb new file mode 100644 index 000000000..74ca0235b --- /dev/null +++ b/db/migrate/20191004095229_change_reserved_domains_name_to_not_null.rb @@ -0,0 +1,5 @@ +class ChangeReservedDomainsNameToNotNull < ActiveRecord::Migration + def change + change_column_null :reserved_domains, :name, false + end +end diff --git a/db/migrate/20191004103144_add_reserved_domains_name_uniq_constraint.rb b/db/migrate/20191004103144_add_reserved_domains_name_uniq_constraint.rb new file mode 100644 index 000000000..81202d28a --- /dev/null +++ b/db/migrate/20191004103144_add_reserved_domains_name_uniq_constraint.rb @@ -0,0 +1,13 @@ +class AddReservedDomainsNameUniqConstraint < ActiveRecord::Migration + def up + execute <<-SQL + ALTER TABLE reserved_domains ADD CONSTRAINT uniq_reserved_domains_name UNIQUE (name); + SQL + end + + def down + execute <<-SQL + ALTER TABLE reserved_domains DROP CONSTRAINT uniq_reserved_domains_name; + SQL + end +end diff --git a/db/migrate/20191004105643_change_blocked_domains_name_to_not_null.rb b/db/migrate/20191004105643_change_blocked_domains_name_to_not_null.rb new file mode 100644 index 000000000..ef5fbf5cf --- /dev/null +++ b/db/migrate/20191004105643_change_blocked_domains_name_to_not_null.rb @@ -0,0 +1,5 @@ +class ChangeBlockedDomainsNameToNotNull < ActiveRecord::Migration + def change + change_column_null :blocked_domains, :name, false + end +end diff --git a/db/migrate/20191004105732_add_blocked_domains_name_uniq_constraint.rb b/db/migrate/20191004105732_add_blocked_domains_name_uniq_constraint.rb new file mode 100644 index 000000000..7542831f9 --- /dev/null +++ b/db/migrate/20191004105732_add_blocked_domains_name_uniq_constraint.rb @@ -0,0 +1,13 @@ +class AddBlockedDomainsNameUniqConstraint < ActiveRecord::Migration + def up + execute <<-SQL + ALTER TABLE blocked_domains ADD CONSTRAINT uniq_blocked_domains_name UNIQUE (name); + SQL + end + + def down + execute <<-SQL + ALTER TABLE blocked_domains DROP CONSTRAINT uniq_blocked_domains_name; + SQL + end +end diff --git a/db/migrate/20191004110234_remove_blocked_domains_name_index.rb b/db/migrate/20191004110234_remove_blocked_domains_name_index.rb new file mode 100644 index 000000000..04dd0c1fb --- /dev/null +++ b/db/migrate/20191004110234_remove_blocked_domains_name_index.rb @@ -0,0 +1,5 @@ +class RemoveBlockedDomainsNameIndex < ActiveRecord::Migration + def change + remove_index :blocked_domains, name: 'index_blocked_domains_on_name' + end +end diff --git a/db/migrate/20191004154844_add_constraints.rb b/db/migrate/20191004154844_add_constraints.rb new file mode 100644 index 000000000..4da2a50e3 --- /dev/null +++ b/db/migrate/20191004154844_add_constraints.rb @@ -0,0 +1,19 @@ +class AddConstraints < ActiveRecord::Migration + def change + change_column_null :registrant_verifications, :domain_name, false + change_column_null :registrant_verifications, :verification_token, false + change_column_null :registrant_verifications, :action, false + change_column_null :registrant_verifications, :domain_id, false + change_column_null :registrant_verifications, :action_type, false + add_foreign_key :registrant_verifications, :domains + + change_column_null :zones, :origin, false + change_column_null :zones, :ttl, false + change_column_null :zones, :refresh, false + change_column_null :zones, :retry, false + change_column_null :zones, :expire, false + change_column_null :zones, :minimum_ttl, false + change_column_null :zones, :email, false + change_column_null :zones, :master_nameserver, false + end +end diff --git a/db/migrate/20191005162437_add_constraints_part_ii.rb b/db/migrate/20191005162437_add_constraints_part_ii.rb new file mode 100644 index 000000000..eb7d289e8 --- /dev/null +++ b/db/migrate/20191005162437_add_constraints_part_ii.rb @@ -0,0 +1,6 @@ +class AddConstraintsPartIi < ActiveRecord::Migration + def change + change_column_null :white_ips, :registrar_id, false + add_foreign_key :white_ips, :registrars + end +end diff --git a/db/migrate/20191007123000_add_constraints_part_iii.rb b/db/migrate/20191007123000_add_constraints_part_iii.rb new file mode 100644 index 000000000..dae4bb83b --- /dev/null +++ b/db/migrate/20191007123000_add_constraints_part_iii.rb @@ -0,0 +1,7 @@ +class AddConstraintsPartIii < ActiveRecord::Migration + def change + change_column_null :domains, :name, false + change_column_null :domains, :name_puny, false + change_column_null :domains, :name_dirty, false + end +end diff --git a/db/migrate/20191008024334_remove_csr_crt_from_users.rb b/db/migrate/20191008024334_remove_csr_crt_from_users.rb new file mode 100644 index 000000000..42c0d965b --- /dev/null +++ b/db/migrate/20191008024334_remove_csr_crt_from_users.rb @@ -0,0 +1,6 @@ +class RemoveCsrCrtFromUsers < ActiveRecord::Migration + def change + remove_column :users, :csr, :text + remove_column :users, :crt, :text + end +end \ No newline at end of file diff --git a/db/migrate/20191024153351_add_invoice_items_quantity_constraint.rb b/db/migrate/20191024153351_add_invoice_items_quantity_constraint.rb new file mode 100644 index 000000000..9f99fa607 --- /dev/null +++ b/db/migrate/20191024153351_add_invoice_items_quantity_constraint.rb @@ -0,0 +1,14 @@ +class AddInvoiceItemsQuantityConstraint < ActiveRecord::Migration + def up + execute <<~SQL + ALTER TABLE invoice_items ADD CONSTRAINT invoice_items_quantity_is_positive + CHECK (quantity > 0); + SQL + end + + def down + execute <<~SQL + ALTER TABLE invoice_items DROP CONSTRAINT invoice_items_quantity_is_positive; + SQL + end +end diff --git a/db/migrate/20191024160038_add_invoices_due_date_constraint.rb b/db/migrate/20191024160038_add_invoices_due_date_constraint.rb new file mode 100644 index 000000000..313f5d276 --- /dev/null +++ b/db/migrate/20191024160038_add_invoices_due_date_constraint.rb @@ -0,0 +1,14 @@ +class AddInvoicesDueDateConstraint < ActiveRecord::Migration + def up + execute <<~SQL + ALTER TABLE invoices ADD CONSTRAINT invoices_due_date_is_not_before_issue_date + CHECK (due_date >= issue_date); + SQL + end + + def down + execute <<~SQL + ALTER TABLE invoices DROP CONSTRAINT invoices_due_date_is_not_before_issue_date; + SQL + end +end diff --git a/db/migrate/20191203083643_add_force_delete_start_to_domains.rb b/db/migrate/20191203083643_add_force_delete_start_to_domains.rb new file mode 100644 index 000000000..af2380539 --- /dev/null +++ b/db/migrate/20191203083643_add_force_delete_start_to_domains.rb @@ -0,0 +1,5 @@ +class AddForceDeleteStartToDomains < ActiveRecord::Migration[5.0] + def change + add_column :domains, :force_delete_start, :datetime + end +end diff --git a/db/migrate/20191206183853_remove_registrant_verifications_domain_name.rb b/db/migrate/20191206183853_remove_registrant_verifications_domain_name.rb new file mode 100644 index 000000000..0212c60ea --- /dev/null +++ b/db/migrate/20191206183853_remove_registrant_verifications_domain_name.rb @@ -0,0 +1,5 @@ +class RemoveRegistrantVerificationsDomainName < ActiveRecord::Migration[5.0] + def change + remove_column :registrant_verifications, :domain_name + end +end diff --git a/db/migrate/20191212133136_remove_fill_ident_country_function.rb b/db/migrate/20191212133136_remove_fill_ident_country_function.rb new file mode 100644 index 000000000..7a99ad855 --- /dev/null +++ b/db/migrate/20191212133136_remove_fill_ident_country_function.rb @@ -0,0 +1,7 @@ +class RemoveFillIdentCountryFunction < ActiveRecord::Migration[5.0] + def change + execute <<~SQL + DROP FUNCTION fill_ident_country(); + SQL + end +end diff --git a/db/migrate/20191227110904_add_json_based_version_to_registrant_verifications.rb b/db/migrate/20191227110904_add_json_based_version_to_registrant_verifications.rb new file mode 100644 index 000000000..6300cddf1 --- /dev/null +++ b/db/migrate/20191227110904_add_json_based_version_to_registrant_verifications.rb @@ -0,0 +1,24 @@ +class AddJsonBasedVersionToRegistrantVerifications < ActiveRecord::Migration[5.0] + def change + name = 'registrant_verification' + table_name = "log_#{name.tableize}" + + create_table table_name do |t| + t.string :item_type, null: false + t.integer :item_id, null: false + t.string :event, null: false + t.string :whodunnit + t.json :object + t.json :object_changes + t.datetime :created_at + t.string :session + end + add_index table_name, [:item_type, :item_id] + add_index table_name, :whodunnit + + add_column name.tableize, :creator_id_tmp, :integer + add_column name.tableize, :updater_id_tmp, :integer + rename_column name.tableize, :creator_id_tmp, :creator_id + rename_column name.tableize, :updater_id_tmp, :updater_id + end +end diff --git a/db/migrate/20200113091254_add_uuid_to_log_registrant_verification.rb b/db/migrate/20200113091254_add_uuid_to_log_registrant_verification.rb new file mode 100644 index 000000000..4e130fc8e --- /dev/null +++ b/db/migrate/20200113091254_add_uuid_to_log_registrant_verification.rb @@ -0,0 +1,7 @@ +class AddUuidToLogRegistrantVerification < ActiveRecord::Migration[5.0] + def change + change_table 'log_registrant_verifications' do |t| + t.string :uuid + end + end +end diff --git a/db/migrate/20200115102202_add_force_delete_data_to_domains.rb b/db/migrate/20200115102202_add_force_delete_data_to_domains.rb new file mode 100644 index 000000000..2ecc7ceaf --- /dev/null +++ b/db/migrate/20200115102202_add_force_delete_data_to_domains.rb @@ -0,0 +1,5 @@ +class AddForceDeleteDataToDomains < ActiveRecord::Migration[5.0] + def change + add_column :domains, :force_delete_data, :hstore + end +end diff --git a/db/migrate/20200130092113_create_payment_orders.rb b/db/migrate/20200130092113_create_payment_orders.rb new file mode 100644 index 000000000..97d86a034 --- /dev/null +++ b/db/migrate/20200130092113_create_payment_orders.rb @@ -0,0 +1,15 @@ +class CreatePaymentOrders < ActiveRecord::Migration[5.0] + def change + create_table :payment_orders do |t| + t.string :type, null: false + t.string :status, default: 'issued', null: false + t.belongs_to :invoice, foreign_key: true + t.jsonb :response, null: true + t.string :notes, null: true + t.string :creator_str + t.string :updator_str + + t.timestamps + end + end +end diff --git a/db/migrate/20200203143458_create_payment_order_versions.rb b/db/migrate/20200203143458_create_payment_order_versions.rb new file mode 100644 index 000000000..d02b300e1 --- /dev/null +++ b/db/migrate/20200203143458_create_payment_order_versions.rb @@ -0,0 +1,16 @@ +class CreatePaymentOrderVersions < ActiveRecord::Migration[5.0] + def change + create_table :log_payment_orders do |t| + t.string :item_type, null: false + t.integer :item_id, null: false + t.string :event, null: false + t.string :whodunnit + t.jsonb :object + t.jsonb :object_changes + t.datetime :created_at + t.string :session + t.jsonb :children + t.string :uuid + end + end +end diff --git a/db/migrate/20200204103125_add_e_invoice_sent_at_to_invoice.rb b/db/migrate/20200204103125_add_e_invoice_sent_at_to_invoice.rb new file mode 100644 index 000000000..e0e5f2cd0 --- /dev/null +++ b/db/migrate/20200204103125_add_e_invoice_sent_at_to_invoice.rb @@ -0,0 +1,5 @@ +class AddEInvoiceSentAtToInvoice < ActiveRecord::Migration[5.0] + def change + add_column :invoices, :e_invoice_sent_at, :datetime + end +end diff --git a/db/migrate/20200311114649_update_zone_generation_migration.rb b/db/migrate/20200311114649_update_zone_generation_migration.rb new file mode 100644 index 000000000..2c516474d --- /dev/null +++ b/db/migrate/20200311114649_update_zone_generation_migration.rb @@ -0,0 +1,247 @@ +class UpdateZoneGenerationMigration < ActiveRecord::Migration[5.1] + def up + execute <<-SQL + CREATE OR REPLACE FUNCTION generate_zonefile(i_origin character varying) RETURNS text + LANGUAGE plpgsql + AS $_$ + DECLARE + zone_header text := concat('$ORIGIN ', i_origin, '.'); + serial_num varchar; + include_filter varchar := ''; + exclude_filter varchar := ''; + tmp_var text; + ret text; + BEGIN + -- define filters + include_filter = '%.' || i_origin; + + -- for %.%.% + IF i_origin ~ '.' THEN + exclude_filter := ''; + -- for %.% + ELSE + exclude_filter := '%.%.' || i_origin; + END IF; + + SELECT ROUND(extract(epoch from now() at time zone 'utc')) INTO serial_num; + + -- zonefile header + SELECT concat( + format('%-10s', '$ORIGIN .'), chr(10), + format('%-10s', '$TTL'), zf.ttl, chr(10), chr(10), + format('%-10s', i_origin || '.'), 'IN SOA ', zf.master_nameserver, '. ', zf.email, '. (', chr(10), + format('%-17s', ''), format('%-12s', serial_num), '; serial number', chr(10), + format('%-17s', ''), format('%-12s', zf.refresh), '; refresh, seconds', chr(10), + format('%-17s', ''), format('%-12s', zf.retry), '; retry, seconds', chr(10), + format('%-17s', ''), format('%-12s', zf.expire), '; expire, seconds', chr(10), + format('%-17s', ''), format('%-12s', zf.minimum_ttl), '; minimum TTL, seconds', chr(10), + format('%-17s', ''), ')' + ) FROM zones zf WHERE i_origin = zf.origin INTO tmp_var; + + ret = concat(tmp_var, chr(10), chr(10)); + + -- origin ns records + SELECT ns_records FROM zones zf WHERE i_origin = zf.origin INTO tmp_var; + ret := concat(ret, '; Zone NS Records', chr(10), tmp_var, chr(10)); + + -- ns records + SELECT array_to_string( + array( + SELECT concat(d.name_puny, '. IN NS ', coalesce(ns.hostname_puny, ns.hostname), '.') + FROM domains d + JOIN nameservers ns ON ns.domain_id = d.id + WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter + AND NOT ('{serverHold,clientHold,inactive}' && d.statuses) + ORDER BY d.name + ), + chr(10) + ) INTO tmp_var; + + ret := concat(ret, tmp_var, chr(10), chr(10)); + + -- origin a glue records + SELECT a_records FROM zones zf WHERE i_origin = zf.origin INTO tmp_var; + ret := concat(ret, '; Zone A Records', chr(10), tmp_var, chr(10)); + + -- a glue records for other nameservers + SELECT array_to_string( + array( + SELECT concat(coalesce(ns.hostname_puny, ns.hostname), '. IN A ', unnest(ns.ipv4)) + FROM nameservers ns + JOIN domains d ON d.id = ns.domain_id + WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter + AND (ns.hostname LIKE '%.' || d.name) OR (ns.hostname LIKE d.name) + AND d.name <> i_origin + AND ns.ipv4 IS NOT NULL AND ns.ipv4 <> '{}' + AND NOT ('{serverHold,clientHold,inactive}' && d.statuses) + ), chr(10) + ) INTO tmp_var; + + ret := concat(ret, tmp_var, chr(10), chr(10)); + + -- origin aaaa glue records + SELECT a4_records FROM zones zf WHERE i_origin = zf.origin INTO tmp_var; + ret := concat(ret, '; Zone AAAA Records', chr(10), tmp_var, chr(10)); + + -- aaaa glue records for other nameservers + SELECT array_to_string( + array( + SELECT concat(coalesce(ns.hostname_puny, ns.hostname), '. IN AAAA ', unnest(ns.ipv6)) + FROM nameservers ns + JOIN domains d ON d.id = ns.domain_id + WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter + AND (ns.hostname LIKE '%.' || d.name) OR (ns.hostname LIKE d.name) + AND d.name <> i_origin + AND ns.ipv6 IS NOT NULL AND ns.ipv6 <> '{}' + AND NOT ('{serverHold,clientHold,inactive}' && d.statuses) + ), chr(10) + ) INTO tmp_var; + + ret := concat(ret, tmp_var, chr(10), chr(10)); + + -- ds records + SELECT array_to_string( + array( + SELECT concat( + d.name_puny, '. 3600 IN DS ', dk.ds_key_tag, ' ', + dk.ds_alg, ' ', dk.ds_digest_type, ' ', dk.ds_digest + ) + FROM domains d + JOIN dnskeys dk ON dk.domain_id = d.id + WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter AND dk.flags = 257 + AND NOT ('{serverHold,clientHold,inactive}' && d.statuses) + ), + chr(10) + ) INTO tmp_var; + + ret := concat(ret, '; Zone DS Records', chr(10), tmp_var, chr(10)); + + RETURN ret; + END; + $_$; + SQL + end + + def down + execute <<-SQL + CREATE OR REPLACE FUNCTION generate_zonefile(i_origin character varying) RETURNS text + LANGUAGE plpgsql + AS $_$ + DECLARE + zone_header text := concat('$ORIGIN ', i_origin, '.'); + serial_num varchar; + include_filter varchar := ''; + exclude_filter varchar := ''; + tmp_var text; + ret text; + BEGIN + -- define filters + include_filter = '%.' || i_origin; + + -- for %.%.% + IF i_origin ~ '.' THEN + exclude_filter := ''; + -- for %.% + ELSE + exclude_filter := '%.%.' || i_origin; + END IF; + + SELECT ROUND(extract(epoch from now() at time zone 'utc')) INTO serial_num; + + -- zonefile header + SELECT concat( + format('%-10s', '$ORIGIN .'), chr(10), + format('%-10s', '$TTL'), zf.ttl, chr(10), chr(10), + format('%-10s', i_origin || '.'), 'IN SOA ', zf.master_nameserver, '. ', zf.email, '. (', chr(10), + format('%-17s', ''), format('%-12s', serial_num), '; serial number', chr(10), + format('%-17s', ''), format('%-12s', zf.refresh), '; refresh, seconds', chr(10), + format('%-17s', ''), format('%-12s', zf.retry), '; retry, seconds', chr(10), + format('%-17s', ''), format('%-12s', zf.expire), '; expire, seconds', chr(10), + format('%-17s', ''), format('%-12s', zf.minimum_ttl), '; minimum TTL, seconds', chr(10), + format('%-17s', ''), ')' + ) FROM zones zf WHERE i_origin = zf.origin INTO tmp_var; + + ret = concat(tmp_var, chr(10), chr(10)); + + -- origin ns records + SELECT ns_records FROM zones zf WHERE i_origin = zf.origin INTO tmp_var; + ret := concat(ret, '; Zone NS Records', chr(10), tmp_var, chr(10)); + + -- ns records + SELECT array_to_string( + array( + SELECT concat(d.name_puny, '. IN NS ', coalesce(ns.hostname_puny, ns.hostname), '.') + FROM domains d + JOIN nameservers ns ON ns.domain_id = d.id + WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter + AND NOT ('{serverHold,clientHold,inactive}' && d.statuses) + ORDER BY d.name + ), + chr(10) + ) INTO tmp_var; + + ret := concat(ret, tmp_var, chr(10), chr(10)); + + -- origin a glue records + SELECT a_records FROM zones zf WHERE i_origin = zf.origin INTO tmp_var; + ret := concat(ret, '; Zone A Records', chr(10), tmp_var, chr(10)); + + -- a glue records for other nameservers + SELECT array_to_string( + array( + SELECT concat(coalesce(ns.hostname_puny, ns.hostname), '. IN A ', unnest(ns.ipv4)) + FROM nameservers ns + JOIN domains d ON d.id = ns.domain_id + WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter + AND ns.hostname LIKE '%.' || d.name + AND d.name <> i_origin + AND ns.ipv4 IS NOT NULL AND ns.ipv4 <> '{}' + AND NOT ('{serverHold,clientHold,inactive}' && d.statuses) + ), chr(10) + ) INTO tmp_var; + + ret := concat(ret, tmp_var, chr(10), chr(10)); + + -- origin aaaa glue records + SELECT a4_records FROM zones zf WHERE i_origin = zf.origin INTO tmp_var; + ret := concat(ret, '; Zone AAAA Records', chr(10), tmp_var, chr(10)); + + -- aaaa glue records for other nameservers + SELECT array_to_string( + array( + SELECT concat(coalesce(ns.hostname_puny, ns.hostname), '. IN AAAA ', unnest(ns.ipv6)) + FROM nameservers ns + JOIN domains d ON d.id = ns.domain_id + WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter + AND ns.hostname LIKE '%.' || d.name + AND d.name <> i_origin + AND ns.ipv6 IS NOT NULL AND ns.ipv6 <> '{}' + AND NOT ('{serverHold,clientHold,inactive}' && d.statuses) + ), chr(10) + ) INTO tmp_var; + + ret := concat(ret, tmp_var, chr(10), chr(10)); + + -- ds records + SELECT array_to_string( + array( + SELECT concat( + d.name_puny, '. 3600 IN DS ', dk.ds_key_tag, ' ', + dk.ds_alg, ' ', dk.ds_digest_type, ' ', dk.ds_digest + ) + FROM domains d + JOIN dnskeys dk ON dk.domain_id = d.id + WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter AND dk.flags = 257 + AND NOT ('{serverHold,clientHold,inactive}' && d.statuses) + ), + chr(10) + ) INTO tmp_var; + + ret := concat(ret, '; Zone DS Records', chr(10), tmp_var, chr(10)); + + RETURN ret; + END; + $_$; + SQL + end +end diff --git a/db/migrate/20200417075720_add_registration_deadline_date_to_models.rb b/db/migrate/20200417075720_add_registration_deadline_date_to_models.rb new file mode 100644 index 000000000..8614ec889 --- /dev/null +++ b/db/migrate/20200417075720_add_registration_deadline_date_to_models.rb @@ -0,0 +1,5 @@ +class AddRegistrationDeadlineDateToModels < ActiveRecord::Migration[5.2] + def change + add_column :auctions, :registration_deadline, :datetime + end +end diff --git a/db/migrate/20200421093637_create_disputes.rb b/db/migrate/20200421093637_create_disputes.rb new file mode 100644 index 000000000..b934d3297 --- /dev/null +++ b/db/migrate/20200421093637_create_disputes.rb @@ -0,0 +1,14 @@ +class CreateDisputes < ActiveRecord::Migration[5.2] + def change + create_table :disputes do |t| + t.string :domain_name, null: false + t.string :password, null: false + t.date :expires_at, null: false + t.date :starts_at, null: false + t.text :comment + t.boolean :closed, null: false, default: false + + t.timestamps + end + end +end diff --git a/db/migrate/20200505103316_add_revoked_to_certificate.rb b/db/migrate/20200505103316_add_revoked_to_certificate.rb new file mode 100644 index 000000000..a52c7d14c --- /dev/null +++ b/db/migrate/20200505103316_add_revoked_to_certificate.rb @@ -0,0 +1,5 @@ +class AddRevokedToCertificate < ActiveRecord::Migration[5.2] + def change + add_column :certificates, :revoked, :boolean, null: false, default: false + end +end diff --git a/db/migrate/20200505150413_add_dispute_period_in_months_to_setting.rb b/db/migrate/20200505150413_add_dispute_period_in_months_to_setting.rb new file mode 100644 index 000000000..cffa91b7f --- /dev/null +++ b/db/migrate/20200505150413_add_dispute_period_in_months_to_setting.rb @@ -0,0 +1,5 @@ +class AddDisputePeriodInMonthsToSetting < ActiveRecord::Migration[5.2] + def change + Setting.create(var: 'dispute_period_in_months', value: 36) + end +end diff --git a/db/migrate/20200518104105_add_closed_date_time_and_updator_to_dispute.rb b/db/migrate/20200518104105_add_closed_date_time_and_updator_to_dispute.rb new file mode 100644 index 000000000..1aae02e06 --- /dev/null +++ b/db/migrate/20200518104105_add_closed_date_time_and_updator_to_dispute.rb @@ -0,0 +1,19 @@ +class AddClosedDateTimeAndUpdatorToDispute < ActiveRecord::Migration[5.2] + def up + rename_column :disputes, :closed, :closed_boolean + add_column :disputes, :closed, :datetime + execute 'UPDATE disputes SET closed = updated_at WHERE closed_boolean = true' + execute 'UPDATE disputes SET closed = NULL WHERE closed_boolean = false' + remove_column :disputes, :closed_boolean + add_column :disputes, :initiator, :string + end + + def down + rename_column :disputes, :closed, :closed_datetime + add_column :disputes, :closed, :boolean, null: false, default: false + execute 'UPDATE disputes SET closed = true WHERE closed_datetime != NULL' + execute 'UPDATE disputes SET closed = false WHERE closed_datetime = NULL' + remove_column :disputes, :closed_datetime + remove_column :disputes, :initiator + end +end diff --git a/db/migrate/20200529115011_add_foreign_key_constraint_to_active_storage_attachments_for_blob_id.active_storage.rb b/db/migrate/20200529115011_add_foreign_key_constraint_to_active_storage_attachments_for_blob_id.active_storage.rb new file mode 100644 index 000000000..ff5d72c7e --- /dev/null +++ b/db/migrate/20200529115011_add_foreign_key_constraint_to_active_storage_attachments_for_blob_id.active_storage.rb @@ -0,0 +1,10 @@ +# This migration comes from active_storage (originally 20180723000244) +class AddForeignKeyConstraintToActiveStorageAttachmentsForBlobId < ActiveRecord::Migration[6.0] + def up + return if foreign_key_exists?(:active_storage_attachments, column: :blob_id) + + if table_exists?(:active_storage_blobs) + add_foreign_key :active_storage_attachments, :active_storage_blobs, column: :blob_id + end + end +end diff --git a/db/migrate/20200605100827_create_email_address_verifications.rb b/db/migrate/20200605100827_create_email_address_verifications.rb new file mode 100644 index 000000000..7f618b3a7 --- /dev/null +++ b/db/migrate/20200605100827_create_email_address_verifications.rb @@ -0,0 +1,13 @@ +class CreateEmailAddressVerifications < ActiveRecord::Migration[6.0] + def change + create_table :email_address_verifications do |t| + t.string :email, null: false + t.datetime :verified_at + t.boolean :success, null: false, default: false + t.string :domain, null: false + end + + add_index :email_address_verifications, :email, unique: true + add_index :email_address_verifications, :domain + end +end diff --git a/db/migrate/20200610090110_change_email_verification_fields_to_citext.rb b/db/migrate/20200610090110_change_email_verification_fields_to_citext.rb new file mode 100644 index 000000000..a7e2f8ee8 --- /dev/null +++ b/db/migrate/20200610090110_change_email_verification_fields_to_citext.rb @@ -0,0 +1,13 @@ +class ChangeEmailVerificationFieldsToCitext < ActiveRecord::Migration[6.0] + def up + enable_extension 'citext' + change_column :email_address_verifications, :email, :citext + change_column :email_address_verifications, :domain, :citext + end + + def down + change_column :email_address_verifications, :email, :string + change_column :email_address_verifications, :domain, :string + disable_extension 'citext' + end +end diff --git a/db/migrate/20200630081231_add_legal_doc_optout_to_registrar.rb b/db/migrate/20200630081231_add_legal_doc_optout_to_registrar.rb new file mode 100644 index 000000000..e5bc5a7f1 --- /dev/null +++ b/db/migrate/20200630081231_add_legal_doc_optout_to_registrar.rb @@ -0,0 +1,6 @@ +class AddLegalDocOptoutToRegistrar < ActiveRecord::Migration[6.0] + def change + add_column :registrars, :legaldoc_optout, :boolean, null: false, default: false + add_column :registrars, :legaldoc_optout_comment, :text + end +end diff --git a/db/migrate/20200714115338_add_unique_constraints_to_domain_objects.rb b/db/migrate/20200714115338_add_unique_constraints_to_domain_objects.rb new file mode 100644 index 000000000..8c1b25c73 --- /dev/null +++ b/db/migrate/20200714115338_add_unique_constraints_to_domain_objects.rb @@ -0,0 +1,36 @@ +class AddUniqueConstraintsToDomainObjects < ActiveRecord::Migration[6.0] + def up + + execute <<-SQL + alter table domain_contacts + drop constraint if exists uniq_contact_of_type_per_domain; + SQL + + execute <<-SQL + alter table nameservers + drop constraint if exists uniq_hostname_per_domain; + SQL + + execute <<-SQL + alter table domain_contacts + add constraint uniq_contact_of_type_per_domain unique (domain_id, type, contact_id); + SQL + + execute <<-SQL + alter table nameservers + add constraint uniq_hostname_per_domain unique (domain_id, hostname); + SQL + end + + def down + execute <<-SQL + alter table domain_contacts + drop constraint if exists uniq_contact_of_type_per_domain; + SQL + + execute <<-SQL + alter table nameservers + drop constraint if exists uniq_hostname_per_domain; + SQL + end +end diff --git a/db/migrate/20200807110611_change_registrant_verification_creator_updator_id_to_string.rb b/db/migrate/20200807110611_change_registrant_verification_creator_updator_id_to_string.rb new file mode 100644 index 000000000..144a80ceb --- /dev/null +++ b/db/migrate/20200807110611_change_registrant_verification_creator_updator_id_to_string.rb @@ -0,0 +1,9 @@ +class ChangeRegistrantVerificationCreatorUpdatorIdToString < ActiveRecord::Migration[6.0] + def change + add_column :registrant_verifications, :creator_str, :string + add_column :registrant_verifications, :updator_str, :string + + remove_column :registrant_verifications, :creator_id + remove_column :registrant_verifications, :updater_id + end +end diff --git a/db/migrate/20200811074839_create_setting_entries.rb b/db/migrate/20200811074839_create_setting_entries.rb new file mode 100644 index 000000000..e53a4e015 --- /dev/null +++ b/db/migrate/20200811074839_create_setting_entries.rb @@ -0,0 +1,16 @@ +class CreateSettingEntries < ActiveRecord::Migration[6.0] + def change + create_table :setting_entries do |t| + t.string :code, null: false, index: { unique: true } + t.string :value + t.string :group, null: false + t.string :format, null: false + + # Versioning related + t.string :creator_str + t.string :updator_str + + t.timestamps + end + end +end diff --git a/db/migrate/20200812090409_change_setting_entry_value_to_allow_nil.rb b/db/migrate/20200812090409_change_setting_entry_value_to_allow_nil.rb new file mode 100644 index 000000000..227e0bf85 --- /dev/null +++ b/db/migrate/20200812090409_change_setting_entry_value_to_allow_nil.rb @@ -0,0 +1,5 @@ +class ChangeSettingEntryValueToAllowNil < ActiveRecord::Migration[6.0] + def change + change_column :setting_entries, :value, :string, null: true + end +end diff --git a/db/migrate/20200812125810_create_versions_for_setting_entries.rb b/db/migrate/20200812125810_create_versions_for_setting_entries.rb new file mode 100644 index 000000000..624717658 --- /dev/null +++ b/db/migrate/20200812125810_create_versions_for_setting_entries.rb @@ -0,0 +1,26 @@ +class CreateVersionsForSettingEntries < ActiveRecord::Migration[6.0] + def up + create_table :log_setting_entries, force: :cascade do |t| + t.string :item_type, null: false + t.integer :item_id, null: false + t.string :event, null: false + t.string :whodunnit + t.json :object + t.json :object_changes + t.datetime :created_at + t.string :session + t.json :children + t.string :uuid + end + + add_index 'log_setting_entries', ['item_type', 'item_id'], name: 'index_log_setting_entries_on_item_type_and_item_id', using: :btree + add_index 'log_setting_entries', ['whodunnit'], name: 'index_log_setting_entries_on_whodunnit', using: :btree + end + + def down + remove_index :log_setting_entries, name: 'index_log_setting_entries_on_item_type_and_item_id' + remove_index :log_setting_entries, name: 'index_log_setting_entries_on_whodunnit' + + drop_table :log_setting_entries + end +end diff --git a/db/migrate/20190404140234_change_log_domains_children_type_to_jsonb.rb b/db/migrate/20200902131603_change_log_domains_children_type_to_jsonb.rb similarity index 92% rename from db/migrate/20190404140234_change_log_domains_children_type_to_jsonb.rb rename to db/migrate/20200902131603_change_log_domains_children_type_to_jsonb.rb index b511d7293..fc8e0318a 100644 --- a/db/migrate/20190404140234_change_log_domains_children_type_to_jsonb.rb +++ b/db/migrate/20200902131603_change_log_domains_children_type_to_jsonb.rb @@ -1,5 +1,5 @@ -class ChangeLogDomainsChildrenTypeToJsonb < ActiveRecord::Migration +class ChangeLogDomainsChildrenTypeToJsonb < ActiveRecord::Migration[6.0] def change change_column :log_domains, :children, 'jsonb USING children::jsonb' end -end \ No newline at end of file +end diff --git a/db/seeds.rb b/db/seeds.rb index 5dde23342..c74136b9d 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -1,2 +1,116 @@ # This file should contain all the record creation needed to seed the database with its default values. # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). +# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). +ActiveRecord::Base.transaction do + # Create dynamic Setting objects + SettingEntry.create(code: 'registry_vat_prc', value: '0.2', format: 'float', group: 'billing') + SettingEntry.create(code: 'directo_sales_agent', value: 'HELEN', format: 'string', group: 'billing') + SettingEntry.create(code: 'admin_contacts_min_count', value: '1', format: 'integer', group: 'domain_validation') + SettingEntry.create(code: 'admin_contacts_max_count', value: '10', format: 'integer', group: 'domain_validation') + SettingEntry.create(code: 'tech_contacts_min_count', value: '1', format: 'integer', group: 'domain_validation') + SettingEntry.create(code: 'tech_contacts_max_count', value: '10', format: 'integer', group: 'domain_validation') + SettingEntry.create(code: 'orphans_contacts_in_months', value: '6', format: 'integer', group: 'domain_validation') + SettingEntry.create(code: 'ds_data_allowed', value: 'false', format: 'boolean', group: 'domain_validation') + SettingEntry.create(code: 'key_data_allowed', value: 'true', format: 'boolean', group: 'domain_validation') + SettingEntry.create(code: 'dnskeys_min_count', value: '0', format: 'integer', group: 'domain_validation') + SettingEntry.create(code: 'dnskeys_max_count', value: '9', format: 'integer', group: 'domain_validation') + SettingEntry.create(code: 'nameserver_required', value: 'false', format: 'boolean', group: 'domain_validation') + SettingEntry.create(code: 'ns_min_count', value: '2', format: 'integer', group: 'domain_validation') + SettingEntry.create(code: 'ns_max_count', value: '11', format: 'integer', group: 'domain_validation') + SettingEntry.create(code: 'expire_pending_confirmation', value: '48', format: 'integer', group: 'domain_validation') + SettingEntry.create(code: 'days_to_renew_domain_before_expire', value: '90', format: 'integer', group: 'domain_expiration') + SettingEntry.create(code: 'expire_warning_period', value: '15', format: 'integer', group: 'domain_expiration') + SettingEntry.create(code: 'redemption_grace_period', value: '30', format: 'integer', group: 'domain_expiration') + SettingEntry.create(code: 'transfer_wait_time', value: '0', format: 'integer', group: 'other') + SettingEntry.create(code: 'ds_digest_type', value: '2', format: 'integer', group: 'other') + SettingEntry.create(code: 'client_side_status_editing_enabled', value: 'false', format: 'boolean', group: 'other') + SettingEntry.create(code: 'api_ip_whitelist_enabled', value: 'false', format: 'boolean', group: 'other') + SettingEntry.create(code: 'registrar_ip_whitelist_enabled', value: 'false', format: 'boolean', group: 'other') + SettingEntry.create(code: 'request_confrimation_on_registrant_change_enabled', value: 'true', format: 'boolean', group: 'other') + SettingEntry.create(code: 'request_confirmation_on_domain_deletion_enabled', value: 'true', format: 'boolean', group: 'other') + SettingEntry.create(code: 'default_language', value: 'en', format: 'string', group: 'other') + SettingEntry.create(code: 'invoice_number_min', value: '131050', format: 'integer', group: 'billing') + SettingEntry.create(code: 'invoice_number_max', value: '149999', format: 'integer', group: 'billing') + SettingEntry.create(code: 'days_to_keep_invoices_active', value: '30', format: 'integer', group: 'billing') + SettingEntry.create(code: 'days_to_keep_overdue_invoices_active', value: '0', format: 'integer', group: 'billing') + SettingEntry.create(code: 'minimum_deposit', value: '0.0', format: 'float', group: 'billing') + SettingEntry.create(code: 'directo_receipt_payment_term', value: 'R', format: 'string', group: 'billing') + SettingEntry.create(code: 'directo_receipt_product_name', value: 'ETTEM06', format: 'string', group: 'billing') + SettingEntry.create(code: 'registry_billing_email', value: 'info@internet.ee', format: 'string', group: 'billing') + SettingEntry.create(code: 'registry_invoice_contact', value: 'Martti Õigus', format: 'string', group: 'billing') + SettingEntry.create(code: 'registry_vat_no', value: 'EE101286464', format: 'string', group: 'billing') + SettingEntry.create(code: 'registry_bank', value: 'LHV Pank', format: 'string', group: 'billing') + SettingEntry.create(code: 'registry_iban', value: 'EE557700771000598731', format: 'string', group: 'billing') + SettingEntry.create(code: 'registry_swift', value: 'LHVBEE22', format: 'string', group: 'billing') + SettingEntry.create(code: 'registry_email', value: 'info@internet.ee', format: 'string', group: 'contacts') + SettingEntry.create(code: 'registry_phone', value: '+372 727 1000', format: 'string', group: 'contacts') + SettingEntry.create(code: 'registry_url', value: 'www.internet.ee', format: 'string', group: 'contacts') + SettingEntry.create(code: 'registry_street', value: 'Paldiski mnt 80', format: 'string', group: 'contacts') + SettingEntry.create(code: 'registry_city', value: 'Tallinn', format: 'string', group: 'contacts') + SettingEntry.create(code: 'registry_state', value: 'Harjumaa', format: 'string', group: 'contacts') + SettingEntry.create(code: 'registry_country_code', value: 'EE', format: 'string', group: 'contacts') + SettingEntry.create(code: 'expiration_reminder_mail', value: '2', format: 'integer', group: 'domain_expiration') + SettingEntry.create(code: 'directo_monthly_number_min', value: '309901', format: 'integer', group: 'billing') + SettingEntry.create(code: 'directo_monthly_number_max', value: '309999', format: 'integer', group: 'billing') + SettingEntry.create(code: 'registry_bank_code', value: '689', format: 'string', group: 'billing') + SettingEntry.create(code: 'registry_reg_no', value: '90010019', format: 'string', group: 'contacts') + SettingEntry.create(code: 'registry_zip', value: '10617', format: 'string', group: 'contacts') + SettingEntry.create(code: 'registry_juridical_name', value: 'Eesti Interneti SA', format: 'string', group: 'contacts') + SettingEntry.create(code: 'address_processing', value: 'true', format: 'boolean', group: 'other') + SettingEntry.create(code: 'directo_monthly_number_last', value: '309901', format: 'integer', group: 'billing') + SettingEntry.create(code: 'dispute_period_in_months', value: '36', format: 'integer', group: 'other') + SettingEntry.create(code: 'registry_whois_disclaimer', value: 'Search results may not be used for commercial, advertising, recompilation, repackaging, redistribution, reuse, obscuring or other similar activities.', format: 'string', group: 'contacts') + SettingEntry.create(code: 'legal_document_is_mandatory', value: 'true', format: 'boolean', group: 'domain_validation') + + AdminUser.where(username: 'admin').first_or_create!( + username: 'admin', + email: 'admin@domain.tld', + password: 'adminadmin', + password_confirmation: 'adminadmin', + identity_code: '38001085718', + country_code: 'EE', + roles: ['admin'] + ) + + # First registrar + Registrar.where(name: 'Registrar First').first_or_create!( + name: 'Registrar First', + reg_no: '90010019', + accounting_customer_code: '1234', + language: 'EE', + reference_no: '11', + # vat_rate: '0.2', + vat_no: 'EE101286464', + address_country_code: 'EE', + address_state: 'Harjumaa', + address_city: 'Tallinn', + address_street: 'Tänav 1', + address_zip: '1234546', + email: 'registrar@first.tld', + code: 'REG1' + ) + +# registrar.accounts.create!(account_type: Account::CASH, currency: 'EUR') + +# ApiUser.create!( +# username: 'api_first', +# password: 'api_first', +# identity_code: '38001085718', +# active: true, +# registrar: registrar, +# roles: ['epp'] +# ) + + + +# ZonefileSetting.create!( +# origin: 'tld', +# ttl: 43200, +# refresh: 3600, +# retry: 900, +# expire: 1209600, +# minimum_ttl: 3600, +# email: 'admin.domain.tld', +# master_nameserver: 'ns.tld' +# ) +end diff --git a/db/structure.sql b/db/structure.sql index d8dcacf5d..0ce89f0d2 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -1,6 +1,6 @@ --- --- PostgreSQL database dump --- +--- +--- PostgreSQL database dump +--- SET statement_timeout = 0; SET lock_timeout = 0; @@ -8,6 +8,7 @@ SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config('search_path', '', false); SET check_function_bodies = false; +SET xmloption = content; SET client_min_messages = warning; -- @@ -38,6 +39,20 @@ CREATE EXTENSION IF NOT EXISTS btree_gist WITH SCHEMA public; COMMENT ON EXTENSION btree_gist IS 'support for indexing common datatypes in GiST'; +-- +-- Name: citext; Type: EXTENSION; Schema: -; Owner: - +-- + +CREATE EXTENSION IF NOT EXISTS citext WITH SCHEMA public; + + +-- +-- Name: EXTENSION citext; Type: COMMENT; Schema: -; Owner: - +-- + +COMMENT ON EXTENSION citext IS 'data type for case-insensitive character strings'; + + -- -- Name: hstore; Type: EXTENSION; Schema: -; Owner: - -- @@ -66,106 +81,6 @@ CREATE EXTENSION IF NOT EXISTS pgcrypto WITH SCHEMA public; COMMENT ON EXTENSION pgcrypto IS 'cryptographic functions'; --- --- Name: fill_ident_country(); Type: FUNCTION; Schema: public; Owner: - --- - -CREATE FUNCTION public.fill_ident_country() RETURNS boolean - LANGUAGE plpgsql - AS $_$ - DECLARE - changed BOOLEAN; - multiplier INT []; - multiplier2 INT []; - multiplier3 INT []; - multiplier4 INT []; - r RECORD; - control TEXT; - total INT; - i INT; - mod INT; - counter INT; - BEGIN - - multiplier := ARRAY [1, 2, 3, 4, 5, 6, 7, 8, 9, 1]; - multiplier2 := ARRAY [3, 4, 5, 6, 7, 8, 9, 1, 2, 3]; - multiplier3 := ARRAY [1, 2, 3, 4, 5, 6, 7]; - multiplier4 := ARRAY [3, 4, 5, 6, 7, 8, 9]; - - FOR r IN SELECT id, ident FROM contacts WHERE ident_type = 'priv' AND ident_country_code IS NULL - LOOP - IF (length(r.ident) = 11 AND (r.ident ~ '^[0-9]+$') AND (substring(r.ident, 1, 1) = '3' OR substring(r.ident, 1, 1) = '4' OR substring(r.ident, 1, 1) = '5' OR substring(r.ident, 1, 1) = '6')) - THEN - total := 0; - counter := 1; - FOREACH i IN ARRAY multiplier - LOOP - total := (total + (i * to_number(substring(r.ident, counter, 1), '9'))); - counter := (counter + 1); - END LOOP; - mod := (total % 11); - counter := 1; - IF (mod >= 10) - THEN - total = 0; - FOREACH i IN ARRAY multiplier2 - LOOP - total := (total + (i * to_number(substring(r.ident, counter, 1), '9'))); - counter := (counter + 1); - END LOOP; - mod := (total % 11); - END IF; - IF (mod = 10) - THEN - mod := 0; - END IF; - IF (substring(r.ident, 11, 1) = to_char(mod, 'FM999MI')) - THEN - UPDATE contacts SET ident_country_code = 'EE' WHERE id = r.id; - END IF; - total := 0; - END IF; - END LOOP; - - FOR r IN SELECT id, ident FROM contacts WHERE ident_type = 'org' AND ident_country_code IS NULL - LOOP - IF (length(r.ident) = 8 AND (r.ident ~ '^[0-9]+$') AND (substring(r.ident, 1, 1) = '1' OR substring(r.ident, 1, 1) = '8' OR substring(r.ident, 1, 1) = '9')) - THEN - total := 0; - counter := 1; - FOREACH i IN ARRAY multiplier3 - LOOP - total := (total + (i * to_number(substring(r.ident, counter, 1), '9'))); - counter := (counter + 1); - END LOOP; - mod := total % 11; - total := 0; - counter := 1; - IF (mod >= 10) - THEN - total = 0; - FOREACH i IN ARRAY multiplier4 - LOOP - total := (total + (i * to_number(substring(r.ident, counter, 1), '9'))); - counter := (counter + 1); - END LOOP; - mod := (total % 11); - END IF; - IF (mod = 10) - THEN - mod := 0; - END IF; - IF (substring(r.ident, 8, 1) = to_char(mod, 'FM999MI')) - THEN - UPDATE contacts SET ident_country_code = 'EE' WHERE id = r.id; - END IF; - END IF; - END LOOP; - RETURN changed; - END; - $_$; - - -- -- Name: generate_zonefile(character varying); Type: FUNCTION; Schema: public; Owner: - -- @@ -239,7 +154,7 @@ CREATE FUNCTION public.generate_zonefile(i_origin character varying) RETURNS tex FROM nameservers ns JOIN domains d ON d.id = ns.domain_id WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter - AND ns.hostname LIKE '%.' || d.name + AND (ns.hostname LIKE '%.' || d.name) OR (ns.hostname LIKE d.name) AND d.name <> i_origin AND ns.ipv4 IS NOT NULL AND ns.ipv4 <> '{}' AND NOT ('{serverHold,clientHold,inactive}' && d.statuses) @@ -259,7 +174,7 @@ CREATE FUNCTION public.generate_zonefile(i_origin character varying) RETURNS tex FROM nameservers ns JOIN domains d ON d.id = ns.domain_id WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter - AND ns.hostname LIKE '%.' || d.name + AND (ns.hostname LIKE '%.' || d.name) OR (ns.hostname LIKE d.name) AND d.name <> i_origin AND ns.ipv6 IS NOT NULL AND ns.ipv6 <> '{}' AND NOT ('{serverHold,clientHold,inactive}' && d.statuses) @@ -402,6 +317,18 @@ CREATE SEQUENCE public.actions_id_seq ALTER SEQUENCE public.actions_id_seq OWNED BY public.actions.id; +-- +-- Name: ar_internal_metadata; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- + +CREATE TABLE public.ar_internal_metadata ( + key character varying NOT NULL, + value character varying, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + -- -- Name: auctions; Type: TABLE; Schema: public; Owner: -; Tablespace: -- @@ -412,7 +339,8 @@ CREATE TABLE public.auctions ( status character varying NOT NULL, uuid uuid DEFAULT public.gen_random_uuid() NOT NULL, created_at timestamp without time zone NOT NULL, - registration_code character varying + registration_code character varying, + registration_deadline timestamp without time zone ); @@ -492,8 +420,7 @@ CREATE TABLE public.bank_transactions ( created_at timestamp without time zone, updated_at timestamp without time zone, creator_str character varying, - updator_str character varying, - in_directo boolean DEFAULT false + updator_str character varying ); @@ -526,7 +453,7 @@ CREATE TABLE public.blocked_domains ( updated_at timestamp without time zone, creator_str character varying, updator_str character varying, - name character varying + name character varying NOT NULL ); @@ -564,7 +491,8 @@ CREATE TABLE public.certificates ( updated_at timestamp without time zone, common_name character varying, md5 character varying, - interface character varying + interface character varying, + revoked boolean DEFAULT false NOT NULL ); @@ -602,7 +530,7 @@ CREATE TABLE public.contacts ( ident character varying, ident_type character varying, auth_info character varying NOT NULL, - name character varying, + name character varying NOT NULL, org_name character varying, registrar_id integer NOT NULL, creator_str character varying, @@ -645,6 +573,15 @@ CREATE SEQUENCE public.contacts_id_seq ALTER SEQUENCE public.contacts_id_seq OWNED BY public.contacts.id; +-- +-- Name: data_migrations; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- + +CREATE TABLE public.data_migrations ( + version character varying NOT NULL +); + + -- -- Name: directos; Type: TABLE; Schema: public; Owner: -; Tablespace: -- @@ -680,6 +617,43 @@ CREATE SEQUENCE public.directos_id_seq ALTER SEQUENCE public.directos_id_seq OWNED BY public.directos.id; +-- +-- Name: disputes; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- + +CREATE TABLE public.disputes ( + id bigint NOT NULL, + domain_name character varying NOT NULL, + password character varying NOT NULL, + expires_at date NOT NULL, + starts_at date NOT NULL, + comment text, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + closed timestamp without time zone, + initiator character varying +); + + +-- +-- Name: disputes_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.disputes_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: disputes_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.disputes_id_seq OWNED BY public.disputes.id; + + -- -- Name: dnskeys; Type: TABLE; Schema: public; Owner: -; Tablespace: -- @@ -802,7 +776,7 @@ ALTER SEQUENCE public.domain_transfers_id_seq OWNED BY public.domain_transfers.i CREATE TABLE public.domains ( id integer NOT NULL, - name character varying, + name character varying NOT NULL, registrar_id integer NOT NULL, registered_at timestamp without time zone, valid_to timestamp without time zone NOT NULL, @@ -810,8 +784,8 @@ CREATE TABLE public.domains ( transfer_code character varying NOT NULL, created_at timestamp without time zone, updated_at timestamp without time zone, - name_dirty character varying, - name_puny character varying, + name_dirty character varying NOT NULL, + name_puny character varying NOT NULL, period integer, period_unit character varying(1), creator_str character varying, @@ -831,7 +805,9 @@ CREATE TABLE public.domains ( upid integer, up_date timestamp without time zone, uuid uuid DEFAULT public.gen_random_uuid() NOT NULL, - locked_by_registrant_at timestamp without time zone + locked_by_registrant_at timestamp without time zone, + force_delete_start timestamp without time zone, + force_delete_data public.hstore ); @@ -854,6 +830,98 @@ CREATE SEQUENCE public.domains_id_seq ALTER SEQUENCE public.domains_id_seq OWNED BY public.domains.id; +-- +-- Name: email_address_verifications; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- + +CREATE TABLE public.email_address_verifications ( + id bigint NOT NULL, + email public.citext NOT NULL, + verified_at timestamp without time zone, + success boolean DEFAULT false NOT NULL, + domain public.citext NOT NULL +); + + +-- +-- Name: email_address_verifications_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.email_address_verifications_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: email_address_verifications_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.email_address_verifications_id_seq OWNED BY public.email_address_verifications.id; + + +-- +-- Name: email_addresses_validations; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- + +CREATE TABLE public.email_addresses_validations ( + id bigint NOT NULL, + email character varying NOT NULL, + validated_at timestamp without time zone +); + + +-- +-- Name: email_addresses_validations_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.email_addresses_validations_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: email_addresses_validations_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.email_addresses_validations_id_seq OWNED BY public.email_addresses_validations.id; + + +-- +-- Name: email_addresses_verifications; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- + +CREATE TABLE public.email_addresses_verifications ( + id bigint NOT NULL, + email character varying NOT NULL, + validated_at timestamp without time zone +); + + +-- +-- Name: email_addresses_verifications_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.email_addresses_verifications_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: email_addresses_verifications_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.email_addresses_verifications_id_seq OWNED BY public.email_addresses_verifications.id; + + -- -- Name: epp_sessions; Type: TABLE; Schema: public; Owner: -; Tablespace: -- @@ -900,7 +968,8 @@ CREATE TABLE public.invoice_items ( created_at timestamp without time zone, updated_at timestamp without time zone, creator_str character varying, - updator_str character varying + updator_str character varying, + CONSTRAINT invoice_items_quantity_is_positive CHECK ((quantity > 0)) ); @@ -936,41 +1005,42 @@ CREATE TABLE public.invoices ( description character varying, reference_no character varying NOT NULL, vat_rate numeric(4,3) NOT NULL, - seller_id integer, seller_name character varying NOT NULL, - seller_reg_no character varying, + seller_reg_no character varying NOT NULL, seller_iban character varying NOT NULL, - seller_bank character varying, - seller_swift character varying, + seller_bank character varying NOT NULL, + seller_swift character varying NOT NULL, seller_vat_no character varying, - seller_country_code character varying, + seller_country_code character varying NOT NULL, seller_state character varying, - seller_street character varying, - seller_city character varying, + seller_street character varying NOT NULL, + seller_city character varying NOT NULL, seller_zip character varying, seller_phone character varying, seller_url character varying, - seller_email character varying, - seller_contact_name character varying, - buyer_id integer, + seller_email character varying NOT NULL, + seller_contact_name character varying NOT NULL, + buyer_id integer NOT NULL, buyer_name character varying NOT NULL, - buyer_reg_no character varying, - buyer_country_code character varying, + buyer_reg_no character varying NOT NULL, + buyer_country_code character varying NOT NULL, buyer_state character varying, - buyer_street character varying, - buyer_city character varying, + buyer_street character varying NOT NULL, + buyer_city character varying NOT NULL, buyer_zip character varying, buyer_phone character varying, buyer_url character varying, - buyer_email character varying, + buyer_email character varying NOT NULL, creator_str character varying, updator_str character varying, - number integer, + number integer NOT NULL, cancelled_at timestamp without time zone, total numeric(10,2) NOT NULL, in_directo boolean DEFAULT false, buyer_vat_no character varying, - issue_date date NOT NULL + issue_date date NOT NULL, + e_invoice_sent_at timestamp without time zone, + CONSTRAINT invoices_due_date_is_not_before_issue_date CHECK ((due_date >= issue_date)) ); @@ -993,49 +1063,6 @@ CREATE SEQUENCE public.invoices_id_seq ALTER SEQUENCE public.invoices_id_seq OWNED BY public.invoices.id; --- --- Name: keyrelays; Type: TABLE; Schema: public; Owner: -; Tablespace: --- - -CREATE TABLE public.keyrelays ( - id integer NOT NULL, - domain_id integer, - pa_date timestamp without time zone, - key_data_flags character varying, - key_data_protocol character varying, - key_data_alg character varying, - key_data_public_key text, - auth_info_pw character varying, - expiry_relative character varying, - expiry_absolute timestamp without time zone, - requester_id integer, - accepter_id integer, - created_at timestamp without time zone, - updated_at timestamp without time zone, - creator_str character varying, - updator_str character varying -); - - --- --- Name: keyrelays_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.keyrelays_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: keyrelays_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.keyrelays_id_seq OWNED BY public.keyrelays.id; - - -- -- Name: legal_documents; Type: TABLE; Schema: public; Owner: -; Tablespace: -- @@ -1466,7 +1493,7 @@ CREATE TABLE public.log_domains ( object_changes json, created_at timestamp without time zone, session character varying, - children jsonb, + children json, uuid character varying ); @@ -1566,44 +1593,6 @@ CREATE SEQUENCE public.log_invoices_id_seq ALTER SEQUENCE public.log_invoices_id_seq OWNED BY public.log_invoices.id; --- --- Name: log_keyrelays; Type: TABLE; Schema: public; Owner: -; Tablespace: --- - -CREATE TABLE public.log_keyrelays ( - id integer NOT NULL, - item_type character varying NOT NULL, - item_id integer NOT NULL, - event character varying NOT NULL, - whodunnit character varying, - object json, - object_changes json, - created_at timestamp without time zone, - session character varying, - children json, - uuid character varying -); - - --- --- Name: log_keyrelays_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.log_keyrelays_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: log_keyrelays_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.log_keyrelays_id_seq OWNED BY public.log_keyrelays.id; - - -- -- Name: log_nameservers; Type: TABLE; Schema: public; Owner: -; Tablespace: -- @@ -1680,6 +1669,81 @@ CREATE SEQUENCE public.log_notifications_id_seq ALTER SEQUENCE public.log_notifications_id_seq OWNED BY public.log_notifications.id; +-- +-- Name: log_payment_orders; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- + +CREATE TABLE public.log_payment_orders ( + id integer NOT NULL, + item_type character varying NOT NULL, + item_id integer NOT NULL, + event character varying NOT NULL, + whodunnit character varying, + object jsonb, + object_changes jsonb, + created_at timestamp without time zone, + session character varying, + children jsonb, + uuid character varying +); + + +-- +-- Name: log_payment_orders_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.log_payment_orders_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: log_payment_orders_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.log_payment_orders_id_seq OWNED BY public.log_payment_orders.id; + + +-- +-- Name: log_registrant_verifications; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- + +CREATE TABLE public.log_registrant_verifications ( + id integer NOT NULL, + item_type character varying NOT NULL, + item_id integer NOT NULL, + event character varying NOT NULL, + whodunnit character varying, + object json, + object_changes json, + created_at timestamp without time zone, + session character varying, + uuid character varying +); + + +-- +-- Name: log_registrant_verifications_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.log_registrant_verifications_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: log_registrant_verifications_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.log_registrant_verifications_id_seq OWNED BY public.log_registrant_verifications.id; + + -- -- Name: log_registrars; Type: TABLE; Schema: public; Owner: -; Tablespace: -- @@ -1756,6 +1820,44 @@ CREATE SEQUENCE public.log_reserved_domains_id_seq ALTER SEQUENCE public.log_reserved_domains_id_seq OWNED BY public.log_reserved_domains.id; +-- +-- Name: log_setting_entries; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- + +CREATE TABLE public.log_setting_entries ( + id bigint NOT NULL, + item_type character varying NOT NULL, + item_id integer NOT NULL, + event character varying NOT NULL, + whodunnit character varying, + object json, + object_changes json, + created_at timestamp without time zone, + session character varying, + children json, + uuid character varying +); + + +-- +-- Name: log_setting_entries_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.log_setting_entries_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: log_setting_entries_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.log_setting_entries_id_seq OWNED BY public.log_setting_entries.id; + + -- -- Name: log_settings; Type: TABLE; Schema: public; Owner: -; Tablespace: -- @@ -1946,6 +2048,43 @@ CREATE SEQUENCE public.notifications_id_seq ALTER SEQUENCE public.notifications_id_seq OWNED BY public.notifications.id; +-- +-- Name: payment_orders; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- + +CREATE TABLE public.payment_orders ( + id integer NOT NULL, + type character varying NOT NULL, + status character varying DEFAULT 'issued'::character varying NOT NULL, + invoice_id integer, + response jsonb, + notes character varying, + creator_str character varying, + updator_str character varying, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: payment_orders_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.payment_orders_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: payment_orders_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.payment_orders_id_seq OWNED BY public.payment_orders.id; + + -- -- Name: prices; Type: TABLE; Schema: public; Owner: -; Tablespace: -- @@ -2032,13 +2171,14 @@ ALTER SEQUENCE public.que_jobs_job_id_seq OWNED BY public.que_jobs.job_id; CREATE TABLE public.registrant_verifications ( id integer NOT NULL, - domain_name character varying, - verification_token character varying, + verification_token character varying NOT NULL, created_at timestamp without time zone, updated_at timestamp without time zone, - action character varying, - domain_id integer, - action_type character varying + action character varying NOT NULL, + domain_id integer NOT NULL, + action_type character varying NOT NULL, + creator_str character varying, + updator_str character varying ); @@ -2091,7 +2231,9 @@ CREATE TABLE public.registrars ( language character varying NOT NULL, vat_rate numeric(4,3), iban character varying, - settings jsonb DEFAULT '{}'::jsonb NOT NULL + settings jsonb DEFAULT '{}'::jsonb NOT NULL, + legaldoc_optout boolean DEFAULT false NOT NULL, + legaldoc_optout_comment text ); @@ -2125,7 +2267,7 @@ CREATE TABLE public.reserved_domains ( creator_str character varying, updator_str character varying, legacy_id integer, - name character varying, + name character varying NOT NULL, password character varying NOT NULL ); @@ -2158,6 +2300,42 @@ CREATE TABLE public.schema_migrations ( ); +-- +-- Name: setting_entries; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- + +CREATE TABLE public.setting_entries ( + id bigint NOT NULL, + code character varying NOT NULL, + value character varying, + "group" character varying NOT NULL, + format character varying NOT NULL, + creator_str character varying, + updator_str character varying, + created_at timestamp(6) without time zone NOT NULL, + updated_at timestamp(6) without time zone NOT NULL +); + + +-- +-- Name: setting_entries_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.setting_entries_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: setting_entries_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.setting_entries_id_seq OWNED BY public.setting_entries.id; + + -- -- Name: settings; Type: TABLE; Schema: public; Owner: -; Tablespace: -- @@ -2217,8 +2395,6 @@ CREATE TABLE public.users ( country_code character varying, registrar_id integer, active boolean, - csr text, - crt text, type character varying, registrant_ident character varying, encrypted_password character varying DEFAULT ''::character varying NOT NULL, @@ -2289,7 +2465,7 @@ ALTER SEQUENCE public.versions_id_seq OWNED BY public.versions.id; CREATE TABLE public.white_ips ( id integer NOT NULL, - registrar_id integer, + registrar_id integer NOT NULL, ipv4 character varying, ipv6 character varying, interfaces character varying[], @@ -2360,14 +2536,14 @@ ALTER SEQUENCE public.whois_records_id_seq OWNED BY public.whois_records.id; CREATE TABLE public.zones ( id integer NOT NULL, - origin character varying, - ttl integer, - refresh integer, - retry integer, - expire integer, - minimum_ttl integer, - email character varying, - master_nameserver character varying, + origin character varying NOT NULL, + ttl integer NOT NULL, + refresh integer NOT NULL, + retry integer NOT NULL, + expire integer NOT NULL, + minimum_ttl integer NOT NULL, + email character varying NOT NULL, + master_nameserver character varying NOT NULL, created_at timestamp without time zone, updated_at timestamp without time zone, creator_str character varying, @@ -2467,6 +2643,13 @@ ALTER TABLE ONLY public.contacts ALTER COLUMN id SET DEFAULT nextval('public.con ALTER TABLE ONLY public.directos ALTER COLUMN id SET DEFAULT nextval('public.directos_id_seq'::regclass); +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.disputes ALTER COLUMN id SET DEFAULT nextval('public.disputes_id_seq'::regclass); + + -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- @@ -2495,6 +2678,27 @@ ALTER TABLE ONLY public.domain_transfers ALTER COLUMN id SET DEFAULT nextval('pu ALTER TABLE ONLY public.domains ALTER COLUMN id SET DEFAULT nextval('public.domains_id_seq'::regclass); +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.email_address_verifications ALTER COLUMN id SET DEFAULT nextval('public.email_address_verifications_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.email_addresses_validations ALTER COLUMN id SET DEFAULT nextval('public.email_addresses_validations_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.email_addresses_verifications ALTER COLUMN id SET DEFAULT nextval('public.email_addresses_verifications_id_seq'::regclass); + + -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- @@ -2516,13 +2720,6 @@ ALTER TABLE ONLY public.invoice_items ALTER COLUMN id SET DEFAULT nextval('publi ALTER TABLE ONLY public.invoices ALTER COLUMN id SET DEFAULT nextval('public.invoices_id_seq'::regclass); --- --- Name: id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.keyrelays ALTER COLUMN id SET DEFAULT nextval('public.keyrelays_id_seq'::regclass); - - -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- @@ -2621,13 +2818,6 @@ ALTER TABLE ONLY public.log_invoice_items ALTER COLUMN id SET DEFAULT nextval('p ALTER TABLE ONLY public.log_invoices ALTER COLUMN id SET DEFAULT nextval('public.log_invoices_id_seq'::regclass); --- --- Name: id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.log_keyrelays ALTER COLUMN id SET DEFAULT nextval('public.log_keyrelays_id_seq'::regclass); - - -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- @@ -2642,6 +2832,20 @@ ALTER TABLE ONLY public.log_nameservers ALTER COLUMN id SET DEFAULT nextval('pub ALTER TABLE ONLY public.log_notifications ALTER COLUMN id SET DEFAULT nextval('public.log_notifications_id_seq'::regclass); +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.log_payment_orders ALTER COLUMN id SET DEFAULT nextval('public.log_payment_orders_id_seq'::regclass); + + +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.log_registrant_verifications ALTER COLUMN id SET DEFAULT nextval('public.log_registrant_verifications_id_seq'::regclass); + + -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- @@ -2656,6 +2860,13 @@ ALTER TABLE ONLY public.log_registrars ALTER COLUMN id SET DEFAULT nextval('publ ALTER TABLE ONLY public.log_reserved_domains ALTER COLUMN id SET DEFAULT nextval('public.log_reserved_domains_id_seq'::regclass); +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.log_setting_entries ALTER COLUMN id SET DEFAULT nextval('public.log_setting_entries_id_seq'::regclass); + + -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- @@ -2691,6 +2902,13 @@ ALTER TABLE ONLY public.nameservers ALTER COLUMN id SET DEFAULT nextval('public. ALTER TABLE ONLY public.notifications ALTER COLUMN id SET DEFAULT nextval('public.notifications_id_seq'::regclass); +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.payment_orders ALTER COLUMN id SET DEFAULT nextval('public.payment_orders_id_seq'::regclass); + + -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- @@ -2726,6 +2944,13 @@ ALTER TABLE ONLY public.registrars ALTER COLUMN id SET DEFAULT nextval('public.r ALTER TABLE ONLY public.reserved_domains ALTER COLUMN id SET DEFAULT nextval('public.reserved_domains_id_seq'::regclass); +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.setting_entries ALTER COLUMN id SET DEFAULT nextval('public.setting_entries_id_seq'::regclass); + + -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- @@ -2792,6 +3017,14 @@ ALTER TABLE ONLY public.actions ADD CONSTRAINT actions_pkey PRIMARY KEY (id); +-- +-- Name: ar_internal_metadata_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY public.ar_internal_metadata + ADD CONSTRAINT ar_internal_metadata_pkey PRIMARY KEY (key); + + -- -- Name: auctions_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- @@ -2848,6 +3081,14 @@ ALTER TABLE ONLY public.directos ADD CONSTRAINT directos_pkey PRIMARY KEY (id); +-- +-- Name: disputes_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY public.disputes + ADD CONSTRAINT disputes_pkey PRIMARY KEY (id); + + -- -- Name: dnskeys_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- @@ -2880,6 +3121,30 @@ ALTER TABLE ONLY public.domains ADD CONSTRAINT domains_pkey PRIMARY KEY (id); +-- +-- Name: email_address_verifications_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY public.email_address_verifications + ADD CONSTRAINT email_address_verifications_pkey PRIMARY KEY (id); + + +-- +-- Name: email_addresses_validations_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY public.email_addresses_validations + ADD CONSTRAINT email_addresses_validations_pkey PRIMARY KEY (id); + + +-- +-- Name: email_addresses_verifications_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY public.email_addresses_verifications + ADD CONSTRAINT email_addresses_verifications_pkey PRIMARY KEY (id); + + -- -- Name: epp_sessions_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- @@ -2904,14 +3169,6 @@ ALTER TABLE ONLY public.invoices ADD CONSTRAINT invoices_pkey PRIMARY KEY (id); --- --- Name: keyrelays_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: --- - -ALTER TABLE ONLY public.keyrelays - ADD CONSTRAINT keyrelays_pkey PRIMARY KEY (id); - - -- -- Name: legal_documents_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- @@ -3024,14 +3281,6 @@ ALTER TABLE ONLY public.log_invoices ADD CONSTRAINT log_invoices_pkey PRIMARY KEY (id); --- --- Name: log_keyrelays_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: --- - -ALTER TABLE ONLY public.log_keyrelays - ADD CONSTRAINT log_keyrelays_pkey PRIMARY KEY (id); - - -- -- Name: log_nameservers_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- @@ -3048,6 +3297,22 @@ ALTER TABLE ONLY public.log_notifications ADD CONSTRAINT log_notifications_pkey PRIMARY KEY (id); +-- +-- Name: log_payment_orders_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY public.log_payment_orders + ADD CONSTRAINT log_payment_orders_pkey PRIMARY KEY (id); + + +-- +-- Name: log_registrant_verifications_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY public.log_registrant_verifications + ADD CONSTRAINT log_registrant_verifications_pkey PRIMARY KEY (id); + + -- -- Name: log_registrars_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- @@ -3064,6 +3329,14 @@ ALTER TABLE ONLY public.log_reserved_domains ADD CONSTRAINT log_reserved_domains_pkey PRIMARY KEY (id); +-- +-- Name: log_setting_entries_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY public.log_setting_entries + ADD CONSTRAINT log_setting_entries_pkey PRIMARY KEY (id); + + -- -- Name: log_settings_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- @@ -3104,6 +3377,14 @@ ALTER TABLE ONLY public.notifications ADD CONSTRAINT notifications_pkey PRIMARY KEY (id); +-- +-- Name: payment_orders_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY public.payment_orders + ADD CONSTRAINT payment_orders_pkey PRIMARY KEY (id); + + -- -- Name: prices_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- @@ -3144,6 +3425,14 @@ ALTER TABLE ONLY public.reserved_domains ADD CONSTRAINT reserved_domains_pkey PRIMARY KEY (id); +-- +-- Name: setting_entries_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY public.setting_entries + ADD CONSTRAINT setting_entries_pkey PRIMARY KEY (id); + + -- -- Name: settings_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- @@ -3152,6 +3441,22 @@ ALTER TABLE ONLY public.settings ADD CONSTRAINT settings_pkey PRIMARY KEY (id); +-- +-- Name: uniq_blocked_domains_name; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY public.blocked_domains + ADD CONSTRAINT uniq_blocked_domains_name UNIQUE (name); + + +-- +-- Name: uniq_contact_of_type_per_domain; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY public.domain_contacts + ADD CONSTRAINT uniq_contact_of_type_per_domain UNIQUE (domain_id, type, contact_id); + + -- -- Name: uniq_contact_uuid; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- @@ -3168,6 +3473,22 @@ ALTER TABLE ONLY public.domains ADD CONSTRAINT uniq_domain_uuid UNIQUE (uuid); +-- +-- Name: uniq_hostname_per_domain; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY public.nameservers + ADD CONSTRAINT uniq_hostname_per_domain UNIQUE (domain_id, hostname); + + +-- +-- Name: uniq_reserved_domains_name; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY public.reserved_domains + ADD CONSTRAINT uniq_reserved_domains_name UNIQUE (name); + + -- -- Name: uniq_uuid; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- @@ -3200,6 +3521,14 @@ ALTER TABLE ONLY public.registrars ADD CONSTRAINT unique_name UNIQUE (name); +-- +-- Name: unique_number; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY public.invoices + ADD CONSTRAINT unique_number UNIQUE (number); + + -- -- Name: unique_reference_no; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- @@ -3300,13 +3629,6 @@ CREATE INDEX index_account_activities_on_invoice_id ON public.account_activities CREATE INDEX index_accounts_on_registrar_id ON public.accounts USING btree (registrar_id); --- --- Name: index_blocked_domains_on_name; Type: INDEX; Schema: public; Owner: -; Tablespace: --- - -CREATE INDEX index_blocked_domains_on_name ON public.blocked_domains USING btree (name); - - -- -- Name: index_certificates_on_api_user_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- @@ -3433,6 +3755,13 @@ CREATE INDEX index_domains_on_registrar_id ON public.domains USING btree (regist CREATE INDEX index_domains_on_statuses ON public.domains USING gin (statuses); +-- +-- Name: index_email_address_verifications_on_domain; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX index_email_address_verifications_on_domain ON public.email_address_verifications USING btree (domain); + + -- -- Name: index_epp_sessions_on_updated_at; Type: INDEX; Schema: public; Owner: -; Tablespace: -- @@ -3454,34 +3783,6 @@ CREATE INDEX index_invoice_items_on_invoice_id ON public.invoice_items USING btr CREATE INDEX index_invoices_on_buyer_id ON public.invoices USING btree (buyer_id); --- --- Name: index_invoices_on_seller_id; Type: INDEX; Schema: public; Owner: -; Tablespace: --- - -CREATE INDEX index_invoices_on_seller_id ON public.invoices USING btree (seller_id); - - --- --- Name: index_keyrelays_on_accepter_id; Type: INDEX; Schema: public; Owner: -; Tablespace: --- - -CREATE INDEX index_keyrelays_on_accepter_id ON public.keyrelays USING btree (accepter_id); - - --- --- Name: index_keyrelays_on_domain_id; Type: INDEX; Schema: public; Owner: -; Tablespace: --- - -CREATE INDEX index_keyrelays_on_domain_id ON public.keyrelays USING btree (domain_id); - - --- --- Name: index_keyrelays_on_requester_id; Type: INDEX; Schema: public; Owner: -; Tablespace: --- - -CREATE INDEX index_keyrelays_on_requester_id ON public.keyrelays USING btree (requester_id); - - -- -- Name: index_legal_documents_on_checksum; Type: INDEX; Schema: public; Owner: -; Tablespace: -- @@ -3664,20 +3965,6 @@ CREATE INDEX index_log_invoices_on_item_type_and_item_id ON public.log_invoices CREATE INDEX index_log_invoices_on_whodunnit ON public.log_invoices USING btree (whodunnit); --- --- Name: index_log_keyrelays_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: --- - -CREATE INDEX index_log_keyrelays_on_item_type_and_item_id ON public.log_keyrelays USING btree (item_type, item_id); - - --- --- Name: index_log_keyrelays_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: --- - -CREATE INDEX index_log_keyrelays_on_whodunnit ON public.log_keyrelays USING btree (whodunnit); - - -- -- Name: index_log_nameservers_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- @@ -3706,6 +3993,20 @@ CREATE INDEX index_log_notifications_on_item_type_and_item_id ON public.log_noti CREATE INDEX index_log_notifications_on_whodunnit ON public.log_notifications USING btree (whodunnit); +-- +-- Name: index_log_registrant_verifications_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX index_log_registrant_verifications_on_item_type_and_item_id ON public.log_registrant_verifications USING btree (item_type, item_id); + + +-- +-- Name: index_log_registrant_verifications_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX index_log_registrant_verifications_on_whodunnit ON public.log_registrant_verifications USING btree (whodunnit); + + -- -- Name: index_log_registrars_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- @@ -3734,6 +4035,20 @@ CREATE INDEX index_log_reserved_domains_on_item_type_and_item_id ON public.log_r CREATE INDEX index_log_reserved_domains_on_whodunnit ON public.log_reserved_domains USING btree (whodunnit); +-- +-- Name: index_log_setting_entries_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX index_log_setting_entries_on_item_type_and_item_id ON public.log_setting_entries USING btree (item_type, item_id); + + +-- +-- Name: index_log_setting_entries_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX index_log_setting_entries_on_whodunnit ON public.log_setting_entries USING btree (whodunnit); + + -- -- Name: index_log_settings_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- @@ -3776,6 +4091,13 @@ CREATE INDEX index_nameservers_on_domain_id ON public.nameservers USING btree (d CREATE INDEX index_notifications_on_registrar_id ON public.notifications USING btree (registrar_id); +-- +-- Name: index_payment_orders_on_invoice_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX index_payment_orders_on_invoice_id ON public.payment_orders USING btree (invoice_id); + + -- -- Name: index_prices_on_zone_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- @@ -3797,6 +4119,13 @@ CREATE INDEX index_registrant_verifications_on_created_at ON public.registrant_v CREATE INDEX index_registrant_verifications_on_domain_id ON public.registrant_verifications USING btree (domain_id); +-- +-- Name: index_setting_entries_on_code; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX index_setting_entries_on_code ON public.setting_entries USING btree (code); + + -- -- Name: index_settings_on_thing_type_and_thing_id_and_var; Type: INDEX; Schema: public; Owner: -; Tablespace: -- @@ -3867,6 +4196,13 @@ CREATE INDEX log_domains_object_legacy_id ON public.log_contacts USING btree ((( CREATE INDEX log_nameservers_object_legacy_id ON public.log_contacts USING btree ((((object ->> 'legacy_domain_id'::text))::integer)); +-- +-- Name: unique_data_migrations; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE UNIQUE INDEX unique_data_migrations ON public.data_migrations USING btree (version); + + -- -- Name: unique_schema_migrations; Type: INDEX; Schema: public; Owner: -; Tablespace: -- @@ -3914,6 +4250,22 @@ ALTER TABLE ONLY public.domains ADD CONSTRAINT domains_registrar_id_fk FOREIGN KEY (registrar_id) REFERENCES public.registrars(id); +-- +-- Name: fk_rails_242b91538b; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.invoices + ADD CONSTRAINT fk_rails_242b91538b FOREIGN KEY (buyer_id) REFERENCES public.registrars(id); + + +-- +-- Name: fk_rails_36cff3de9c; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.white_ips + ADD CONSTRAINT fk_rails_36cff3de9c FOREIGN KEY (registrar_id) REFERENCES public.registrars(id); + + -- -- Name: fk_rails_59c422f73d; Type: FK CONSTRAINT; Schema: public; Owner: - -- @@ -4018,6 +4370,22 @@ ALTER TABLE ONLY public.account_activities ADD CONSTRAINT fk_rails_d2cc3c2fa9 FOREIGN KEY (price_id) REFERENCES public.prices(id); +-- +-- Name: fk_rails_f41617a0e9; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.registrant_verifications + ADD CONSTRAINT fk_rails_f41617a0e9 FOREIGN KEY (domain_id) REFERENCES public.domains(id); + + +-- +-- Name: fk_rails_f9dc5857c3; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.payment_orders + ADD CONSTRAINT fk_rails_f9dc5857c3 FOREIGN KEY (invoice_id) REFERENCES public.invoices(id); + + -- -- Name: invoice_items_invoice_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: - -- @@ -4056,767 +4424,430 @@ ALTER TABLE ONLY public.users SET search_path TO "$user",public; -INSERT INTO schema_migrations (version) VALUES ('20140616073945'); +INSERT INTO "schema_migrations" (version) VALUES +('20140616073945'), +('20140620130107'), +('20140627082711'), +('20140701130945'), +('20140702144833'), +('20140702145448'), +('20140724084927'), +('20140730082358'), +('20140730082532'), +('20140730104916'), +('20140730141443'), +('20140731073300'), +('20140731081816'), +('20140801140249'), +('20140804095654'), +('20140808132327'), +('20140813102245'), +('20140813135408'), +('20140815082619'), +('20140815110028'), +('20140815114000'), +('20140819095802'), +('20140819103517'), +('20140822122938'), +('20140826082057'), +('20140826103454'), +('20140827140759'), +('20140828072329'), +('20140828074404'), +('20140828080320'), +('20140828133057'), +('20140902121843'), +('20140911101310'), +('20140911101604'), +('20140925073340'), +('20140925073734'), +('20140925073831'), +('20140925084916'), +('20140925085340'), +('20140925101927'), +('20140926081324'), +('20140926082627'), +('20140926121409'), +('20140929095329'), +('20140930093039'), +('20141001085322'), +('20141006124904'), +('20141006130306'), +('20141008134959'), +('20141009100818'), +('20141009101337'), +('20141010085152'), +('20141010130412'), +('20141014073435'), +('20141015135255'), +('20141015135742'), +('20141105150721'), +('20141111105931'), +('20141114130737'), +('20141120110330'), +('20141120140837'), +('20141121093125'), +('20141124105221'), +('20141125111414'), +('20141126140434'), +('20141127091027'), +('20141202114457'), +('20141203090115'), +('20141210085432'), +('20141211095604'), +('20141215085117'), +('20141216075056'), +('20141216133831'), +('20141218154829'), +('20141229115619'), +('20150105134026'), +('20150109081914'), +('20150110000000'), +('20150110113257'), +('20150122091556'), +('20150122091557'), +('20150128134352'), +('20150129093938'), +('20150129144652'), +('20150130085458'), +('20150130155904'), +('20150130180452'), +('20150130191056'), +('20150200000000'), +('20150202084444'), +('20150202140346'), +('20150203135303'), +('20150212125339'), +('20150213104014'), +('20150217133755'), +('20150217133937'), +('20150223104842'), +('20150226121252'), +('20150226144723'), +('20150227092508'), +('20150227113121'), +('20150302161712'), +('20150303130729'), +('20150303151224'), +('20150305092921'), +('20150318084300'), +('20150318085110'), +('20150318114921'), +('20150319125655'), +('20150320132023'), +('20150330083700'), +('20150402114712'), +('20150407145943'), +('20150408081917'), +('20150410124724'), +('20150410132037'), +('20150413080832'), +('20150413102310'), +('20150413115829'), +('20150413140933'), +('20150414092249'), +('20150414124630'), +('20150414151357'), +('20150415075408'), +('20150416080828'), +('20150416091357'), +('20150416092026'), +('20150416094704'), +('20150417082723'), +('20150421134820'), +('20150422092514'), +('20150422132631'), +('20150422134243'), +('20150423083308'), +('20150427073517'), +('20150428075052'), +('20150429135339'), +('20150430121807'), +('20150504104922'), +('20150504110926'), +('20150505111437'), +('20150511120755'), +('20150512160938'), +('20150513080013'), +('20150514132606'), +('20150515103222'), +('20150518084324'), +('20150519094929'), +('20150519095416'), +('20150519102521'), +('20150519115050'), +('20150519140853'), +('20150519144118'), +('20150520163237'), +('20150520164507'), +('20150521120145'), +('20150522164020'), +('20150525075550'), +('20150601083516'), +('20150601083800'), +('20150603141549'), +('20150603211318'), +('20150603212659'), +('20150609093515'), +('20150609103333'), +('20150610111019'), +('20150610112238'), +('20150610144547'), +('20150611124920'), +('20150612123111'), +('20150612125720'), +('20150701074344'), +('20150703084206'), +('20150703084632'), +('20150706091724'), +('20150707103241'), +('20150707103801'), +('20150707104937'), +('20150707154543'), +('20150709092549'), +('20150713113436'), +('20150722071128'), +('20150803080914'), +('20150810114746'), +('20150810114747'), +('20150825125118'), +('20150827151906'), +('20150903105659'), +('20150910113839'), +('20150915094707'), +('20150921110152'), +('20150921111842'), +('20151028183132'), +('20151029152638'), +('20151112160452'), +('20151117081204'), +('20151120090455'), +('20151124200353'), +('20151125155601'), +('20151127091716'), +('20151130175654'), +('20151202123506'), +('20151209122816'), +('20160106101725'), +('20160108135436'), +('20160113143447'), +('20160118092453'), +('20160118092454'), +('20160218102355'), +('20160225113801'), +('20160225113812'), +('20160226132045'), +('20160226132056'), +('20160304125933'), +('20160311085956'), +('20160311085957'), +('20160405131315'), +('20160411140719'), +('20160414110443'), +('20160421074023'), +('20160429114732'), +('20160527110738'), +('20160629114503'), +('20161004101419'), +('20161227193500'), +('20170221115548'), +('20170419120048'), +('20170420125200'), +('20170422130054'), +('20170422142116'), +('20170422162824'), +('20170423151046'), +('20170423210622'), +('20170423214500'), +('20170423222302'), +('20170423225333'), +('20170424115801'), +('20170506144743'), +('20170506155009'), +('20170506162952'), +('20170506205356'), +('20170506205946'), +('20170506212014'), +('20170509215614'), +('20170604182521'), +('20170606133501'), +('20170606150352'), +('20170606202859'), +('20171009080822'), +('20171009082321'), +('20171025113808'), +('20171025153841'), +('20171121233843'), +('20171123035941'), +('20180112080312'), +('20180112084221'), +('20180112084442'), +('20180120172042'), +('20180120172649'), +('20180120172657'), +('20180120182712'), +('20180120183441'), +('20180121165304'), +('20180122105335'), +('20180123154407'), +('20180123165604'), +('20180123170112'), +('20180125092422'), +('20180126104536'), +('20180126104903'), +('20180129143538'), +('20180129232054'), +('20180129233223'), +('20180206213435'), +('20180206234620'), +('20180207071528'), +('20180207072139'), +('20180211011450'), +('20180211011948'), +('20180212123810'), +('20180212152810'), +('20180212154731'), +('20180213183818'), +('20180214200224'), +('20180214213743'), +('20180218004148'), +('20180228055259'), +('20180228064342'), +('20180228070102'), +('20180228070431'), +('20180228074442'), +('20180306180401'), +('20180306181538'), +('20180306181554'), +('20180306181911'), +('20180306182456'), +('20180306182758'), +('20180306182941'), +('20180306183540'), +('20180306183549'), +('20180308123240'), +('20180309053424'), +('20180309053921'), +('20180309054510'), +('20180310142630'), +('20180313090437'), +('20180313124751'), +('20180314122722'), +('20180327151906'), +('20180331200125'), +('20180422154642'), +('20180612042234'), +('20180612042625'), +('20180612042953'), +('20180613030330'), +('20180613045614'), +('20180713154915'), +('20180801114403'), +('20180808064402'), +('20180816123540'), +('20180823161237'), +('20180823163548'), +('20180823174331'), +('20180823212823'), +('20180824092855'), +('20180824102834'), +('20180824215326'), +('20180825193437'), +('20180825232819'), +('20180826162821'), +('20181001090536'), +('20181002090319'), +('20181017092829'), +('20181017153658'), +('20181017153812'), +('20181017153935'), +('20181017154038'), +('20181017154143'), +('20181017205123'), +('20181022100114'), +('20181108154921'), +('20181129150515'), +('20181212105100'), +('20181212145456'), +('20181212145914'), +('20181213113115'), +('20181217144701'), +('20181217144845'), +('20181220094738'), +('20181220095053'), +('20181223153407'), +('20181226211337'), +('20181227155537'), +('20181227172042'), +('20181230231015'), +('20190102114702'), +('20190102115333'), +('20190102144032'), +('20190209150026'), +('20190302091059'), +('20190302111152'), +('20190311111718'), +('20190312211614'), +('20190315172802'), +('20190319133036'), +('20190322152123'), +('20190322152529'), +('20190328151516'), +('20190328151838'), +('20190415120246'), +('20190426174225'), +('20190506100655'), +('20190510090240'), +('20190510102549'), +('20190515113153'), +('20190516161439'), +('20190520093231'), +('20190617120112'), +('20190617121716'), +('20190617121949'), +('20190617122505'), +('20190620084334'), +('20190811184334'), +('20190811195814'), +('20190811202042'), +('20190811202347'), +('20190811202711'), +('20190811205406'), +('20190917114907'), +('20191004095229'), +('20191004103144'), +('20191004105643'), +('20191004105732'), +('20191004110234'), +('20191004154844'), +('20191005162437'), +('20191007123000'), +('20191008024334'), +('20191024153351'), +('20191024160038'), +('20191203083643'), +('20191206183853'), +('20191212133136'), +('20191227110904'), +('20200113091254'), +('20200115102202'), +('20200130092113'), +('20200203143458'), +('20200204103125'), +('20200311114649'), +('20200417075720'), +('20200421093637'), +('20200505103316'), +('20200505150413'), +('20200518104105'), +('20200529115011'), +('20200605100827'), +('20200610090110'), +('20200630081231'), +('20200714115338'), +('20200807110611'), +('20200811074839'), +('20200812090409'), +('20200812125810'); -INSERT INTO schema_migrations (version) VALUES ('20140620130107'); - -INSERT INTO schema_migrations (version) VALUES ('20140627082711'); - -INSERT INTO schema_migrations (version) VALUES ('20140701130945'); - -INSERT INTO schema_migrations (version) VALUES ('20140702144833'); - -INSERT INTO schema_migrations (version) VALUES ('20140702145448'); - -INSERT INTO schema_migrations (version) VALUES ('20140724084927'); - -INSERT INTO schema_migrations (version) VALUES ('20140730082358'); - -INSERT INTO schema_migrations (version) VALUES ('20140730082532'); - -INSERT INTO schema_migrations (version) VALUES ('20140730104916'); - -INSERT INTO schema_migrations (version) VALUES ('20140730141443'); - -INSERT INTO schema_migrations (version) VALUES ('20140731073300'); - -INSERT INTO schema_migrations (version) VALUES ('20140731081816'); - -INSERT INTO schema_migrations (version) VALUES ('20140801140249'); - -INSERT INTO schema_migrations (version) VALUES ('20140804095654'); - -INSERT INTO schema_migrations (version) VALUES ('20140808132327'); - -INSERT INTO schema_migrations (version) VALUES ('20140813102245'); - -INSERT INTO schema_migrations (version) VALUES ('20140813135408'); - -INSERT INTO schema_migrations (version) VALUES ('20140815082619'); - -INSERT INTO schema_migrations (version) VALUES ('20140815110028'); - -INSERT INTO schema_migrations (version) VALUES ('20140815114000'); - -INSERT INTO schema_migrations (version) VALUES ('20140819095802'); - -INSERT INTO schema_migrations (version) VALUES ('20140819103517'); - -INSERT INTO schema_migrations (version) VALUES ('20140822122938'); - -INSERT INTO schema_migrations (version) VALUES ('20140826082057'); - -INSERT INTO schema_migrations (version) VALUES ('20140826103454'); - -INSERT INTO schema_migrations (version) VALUES ('20140827140759'); - -INSERT INTO schema_migrations (version) VALUES ('20140828072329'); - -INSERT INTO schema_migrations (version) VALUES ('20140828074404'); - -INSERT INTO schema_migrations (version) VALUES ('20140828080320'); - -INSERT INTO schema_migrations (version) VALUES ('20140828133057'); - -INSERT INTO schema_migrations (version) VALUES ('20140902121843'); - -INSERT INTO schema_migrations (version) VALUES ('20140911101310'); - -INSERT INTO schema_migrations (version) VALUES ('20140911101604'); - -INSERT INTO schema_migrations (version) VALUES ('20140925073340'); - -INSERT INTO schema_migrations (version) VALUES ('20140925073734'); - -INSERT INTO schema_migrations (version) VALUES ('20140925073831'); - -INSERT INTO schema_migrations (version) VALUES ('20140925084916'); - -INSERT INTO schema_migrations (version) VALUES ('20140925085340'); - -INSERT INTO schema_migrations (version) VALUES ('20140925101927'); - -INSERT INTO schema_migrations (version) VALUES ('20140926081324'); - -INSERT INTO schema_migrations (version) VALUES ('20140926082627'); - -INSERT INTO schema_migrations (version) VALUES ('20140926121409'); - -INSERT INTO schema_migrations (version) VALUES ('20140929095329'); - -INSERT INTO schema_migrations (version) VALUES ('20140930093039'); - -INSERT INTO schema_migrations (version) VALUES ('20141001085322'); - -INSERT INTO schema_migrations (version) VALUES ('20141006124904'); - -INSERT INTO schema_migrations (version) VALUES ('20141006130306'); - -INSERT INTO schema_migrations (version) VALUES ('20141008134959'); - -INSERT INTO schema_migrations (version) VALUES ('20141009100818'); - -INSERT INTO schema_migrations (version) VALUES ('20141009101337'); - -INSERT INTO schema_migrations (version) VALUES ('20141010085152'); - -INSERT INTO schema_migrations (version) VALUES ('20141010130412'); - -INSERT INTO schema_migrations (version) VALUES ('20141014073435'); - -INSERT INTO schema_migrations (version) VALUES ('20141015135255'); - -INSERT INTO schema_migrations (version) VALUES ('20141015135742'); - -INSERT INTO schema_migrations (version) VALUES ('20141105150721'); - -INSERT INTO schema_migrations (version) VALUES ('20141111105931'); - -INSERT INTO schema_migrations (version) VALUES ('20141114130737'); - -INSERT INTO schema_migrations (version) VALUES ('20141120110330'); - -INSERT INTO schema_migrations (version) VALUES ('20141120140837'); - -INSERT INTO schema_migrations (version) VALUES ('20141121093125'); - -INSERT INTO schema_migrations (version) VALUES ('20141124105221'); - -INSERT INTO schema_migrations (version) VALUES ('20141125111414'); - -INSERT INTO schema_migrations (version) VALUES ('20141126140434'); - -INSERT INTO schema_migrations (version) VALUES ('20141127091027'); - -INSERT INTO schema_migrations (version) VALUES ('20141202114457'); - -INSERT INTO schema_migrations (version) VALUES ('20141203090115'); - -INSERT INTO schema_migrations (version) VALUES ('20141210085432'); - -INSERT INTO schema_migrations (version) VALUES ('20141211095604'); - -INSERT INTO schema_migrations (version) VALUES ('20141215085117'); - -INSERT INTO schema_migrations (version) VALUES ('20141216075056'); - -INSERT INTO schema_migrations (version) VALUES ('20141216133831'); - -INSERT INTO schema_migrations (version) VALUES ('20141218154829'); - -INSERT INTO schema_migrations (version) VALUES ('20141229115619'); - -INSERT INTO schema_migrations (version) VALUES ('20150105134026'); - -INSERT INTO schema_migrations (version) VALUES ('20150109081914'); - -INSERT INTO schema_migrations (version) VALUES ('20150110000000'); - -INSERT INTO schema_migrations (version) VALUES ('20150110113257'); - -INSERT INTO schema_migrations (version) VALUES ('20150122091556'); - -INSERT INTO schema_migrations (version) VALUES ('20150122091557'); - -INSERT INTO schema_migrations (version) VALUES ('20150128134352'); - -INSERT INTO schema_migrations (version) VALUES ('20150129093938'); - -INSERT INTO schema_migrations (version) VALUES ('20150129144652'); - -INSERT INTO schema_migrations (version) VALUES ('20150130085458'); - -INSERT INTO schema_migrations (version) VALUES ('20150130155904'); - -INSERT INTO schema_migrations (version) VALUES ('20150130180452'); - -INSERT INTO schema_migrations (version) VALUES ('20150130191056'); - -INSERT INTO schema_migrations (version) VALUES ('20150200000000'); - -INSERT INTO schema_migrations (version) VALUES ('20150202084444'); - -INSERT INTO schema_migrations (version) VALUES ('20150202140346'); - -INSERT INTO schema_migrations (version) VALUES ('20150203135303'); - -INSERT INTO schema_migrations (version) VALUES ('20150212125339'); - -INSERT INTO schema_migrations (version) VALUES ('20150213104014'); - -INSERT INTO schema_migrations (version) VALUES ('20150217133755'); - -INSERT INTO schema_migrations (version) VALUES ('20150217133937'); - -INSERT INTO schema_migrations (version) VALUES ('20150223104842'); - -INSERT INTO schema_migrations (version) VALUES ('20150226121252'); - -INSERT INTO schema_migrations (version) VALUES ('20150226144723'); - -INSERT INTO schema_migrations (version) VALUES ('20150227092508'); - -INSERT INTO schema_migrations (version) VALUES ('20150227113121'); - -INSERT INTO schema_migrations (version) VALUES ('20150302161712'); - -INSERT INTO schema_migrations (version) VALUES ('20150303130729'); - -INSERT INTO schema_migrations (version) VALUES ('20150303151224'); - -INSERT INTO schema_migrations (version) VALUES ('20150305092921'); - -INSERT INTO schema_migrations (version) VALUES ('20150318084300'); - -INSERT INTO schema_migrations (version) VALUES ('20150318085110'); - -INSERT INTO schema_migrations (version) VALUES ('20150318114921'); - -INSERT INTO schema_migrations (version) VALUES ('20150319125655'); - -INSERT INTO schema_migrations (version) VALUES ('20150320132023'); - -INSERT INTO schema_migrations (version) VALUES ('20150330083700'); - -INSERT INTO schema_migrations (version) VALUES ('20150402114712'); - -INSERT INTO schema_migrations (version) VALUES ('20150407145943'); - -INSERT INTO schema_migrations (version) VALUES ('20150408081917'); - -INSERT INTO schema_migrations (version) VALUES ('20150410124724'); - -INSERT INTO schema_migrations (version) VALUES ('20150410132037'); - -INSERT INTO schema_migrations (version) VALUES ('20150413080832'); - -INSERT INTO schema_migrations (version) VALUES ('20150413102310'); - -INSERT INTO schema_migrations (version) VALUES ('20150413115829'); - -INSERT INTO schema_migrations (version) VALUES ('20150413140933'); - -INSERT INTO schema_migrations (version) VALUES ('20150414092249'); - -INSERT INTO schema_migrations (version) VALUES ('20150414124630'); - -INSERT INTO schema_migrations (version) VALUES ('20150414151357'); - -INSERT INTO schema_migrations (version) VALUES ('20150415075408'); - -INSERT INTO schema_migrations (version) VALUES ('20150416080828'); - -INSERT INTO schema_migrations (version) VALUES ('20150416091357'); - -INSERT INTO schema_migrations (version) VALUES ('20150416092026'); - -INSERT INTO schema_migrations (version) VALUES ('20150416094704'); - -INSERT INTO schema_migrations (version) VALUES ('20150417082723'); - -INSERT INTO schema_migrations (version) VALUES ('20150421134820'); - -INSERT INTO schema_migrations (version) VALUES ('20150422092514'); - -INSERT INTO schema_migrations (version) VALUES ('20150422132631'); - -INSERT INTO schema_migrations (version) VALUES ('20150422134243'); - -INSERT INTO schema_migrations (version) VALUES ('20150423083308'); - -INSERT INTO schema_migrations (version) VALUES ('20150427073517'); - -INSERT INTO schema_migrations (version) VALUES ('20150428075052'); - -INSERT INTO schema_migrations (version) VALUES ('20150429135339'); - -INSERT INTO schema_migrations (version) VALUES ('20150430121807'); - -INSERT INTO schema_migrations (version) VALUES ('20150504104922'); - -INSERT INTO schema_migrations (version) VALUES ('20150504110926'); - -INSERT INTO schema_migrations (version) VALUES ('20150505111437'); - -INSERT INTO schema_migrations (version) VALUES ('20150511120755'); - -INSERT INTO schema_migrations (version) VALUES ('20150512160938'); - -INSERT INTO schema_migrations (version) VALUES ('20150513080013'); - -INSERT INTO schema_migrations (version) VALUES ('20150514132606'); - -INSERT INTO schema_migrations (version) VALUES ('20150515103222'); - -INSERT INTO schema_migrations (version) VALUES ('20150518084324'); - -INSERT INTO schema_migrations (version) VALUES ('20150519094929'); - -INSERT INTO schema_migrations (version) VALUES ('20150519095416'); - -INSERT INTO schema_migrations (version) VALUES ('20150519102521'); - -INSERT INTO schema_migrations (version) VALUES ('20150519115050'); - -INSERT INTO schema_migrations (version) VALUES ('20150519140853'); - -INSERT INTO schema_migrations (version) VALUES ('20150519144118'); - -INSERT INTO schema_migrations (version) VALUES ('20150520163237'); - -INSERT INTO schema_migrations (version) VALUES ('20150520164507'); - -INSERT INTO schema_migrations (version) VALUES ('20150521120145'); - -INSERT INTO schema_migrations (version) VALUES ('20150522164020'); - -INSERT INTO schema_migrations (version) VALUES ('20150525075550'); - -INSERT INTO schema_migrations (version) VALUES ('20150601083516'); - -INSERT INTO schema_migrations (version) VALUES ('20150601083800'); - -INSERT INTO schema_migrations (version) VALUES ('20150603141549'); - -INSERT INTO schema_migrations (version) VALUES ('20150603211318'); - -INSERT INTO schema_migrations (version) VALUES ('20150603212659'); - -INSERT INTO schema_migrations (version) VALUES ('20150609093515'); - -INSERT INTO schema_migrations (version) VALUES ('20150609103333'); - -INSERT INTO schema_migrations (version) VALUES ('20150610111019'); - -INSERT INTO schema_migrations (version) VALUES ('20150610112238'); - -INSERT INTO schema_migrations (version) VALUES ('20150610144547'); - -INSERT INTO schema_migrations (version) VALUES ('20150611124920'); - -INSERT INTO schema_migrations (version) VALUES ('20150612123111'); - -INSERT INTO schema_migrations (version) VALUES ('20150612125720'); - -INSERT INTO schema_migrations (version) VALUES ('20150701074344'); - -INSERT INTO schema_migrations (version) VALUES ('20150703084206'); - -INSERT INTO schema_migrations (version) VALUES ('20150703084632'); - -INSERT INTO schema_migrations (version) VALUES ('20150706091724'); - -INSERT INTO schema_migrations (version) VALUES ('20150707103241'); - -INSERT INTO schema_migrations (version) VALUES ('20150707103801'); - -INSERT INTO schema_migrations (version) VALUES ('20150707104937'); - -INSERT INTO schema_migrations (version) VALUES ('20150707154543'); - -INSERT INTO schema_migrations (version) VALUES ('20150709092549'); - -INSERT INTO schema_migrations (version) VALUES ('20150713113436'); - -INSERT INTO schema_migrations (version) VALUES ('20150722071128'); - -INSERT INTO schema_migrations (version) VALUES ('20150803080914'); - -INSERT INTO schema_migrations (version) VALUES ('20150810114746'); - -INSERT INTO schema_migrations (version) VALUES ('20150810114747'); - -INSERT INTO schema_migrations (version) VALUES ('20150825125118'); - -INSERT INTO schema_migrations (version) VALUES ('20150827151906'); - -INSERT INTO schema_migrations (version) VALUES ('20150903105659'); - -INSERT INTO schema_migrations (version) VALUES ('20150910113839'); - -INSERT INTO schema_migrations (version) VALUES ('20150915094707'); - -INSERT INTO schema_migrations (version) VALUES ('20150921110152'); - -INSERT INTO schema_migrations (version) VALUES ('20150921111842'); - -INSERT INTO schema_migrations (version) VALUES ('20151028183132'); - -INSERT INTO schema_migrations (version) VALUES ('20151029152638'); - -INSERT INTO schema_migrations (version) VALUES ('20151112160452'); - -INSERT INTO schema_migrations (version) VALUES ('20151117081204'); - -INSERT INTO schema_migrations (version) VALUES ('20151120090455'); - -INSERT INTO schema_migrations (version) VALUES ('20151124200353'); - -INSERT INTO schema_migrations (version) VALUES ('20151125155601'); - -INSERT INTO schema_migrations (version) VALUES ('20151127091716'); - -INSERT INTO schema_migrations (version) VALUES ('20151130175654'); - -INSERT INTO schema_migrations (version) VALUES ('20151202123506'); - -INSERT INTO schema_migrations (version) VALUES ('20151209122816'); - -INSERT INTO schema_migrations (version) VALUES ('20160106101725'); - -INSERT INTO schema_migrations (version) VALUES ('20160108135436'); - -INSERT INTO schema_migrations (version) VALUES ('20160113143447'); - -INSERT INTO schema_migrations (version) VALUES ('20160118092453'); - -INSERT INTO schema_migrations (version) VALUES ('20160118092454'); - -INSERT INTO schema_migrations (version) VALUES ('20160218102355'); - -INSERT INTO schema_migrations (version) VALUES ('20160225113801'); - -INSERT INTO schema_migrations (version) VALUES ('20160225113812'); - -INSERT INTO schema_migrations (version) VALUES ('20160226132045'); - -INSERT INTO schema_migrations (version) VALUES ('20160226132056'); - -INSERT INTO schema_migrations (version) VALUES ('20160304125933'); - -INSERT INTO schema_migrations (version) VALUES ('20160311085956'); - -INSERT INTO schema_migrations (version) VALUES ('20160311085957'); - -INSERT INTO schema_migrations (version) VALUES ('20160405131315'); - -INSERT INTO schema_migrations (version) VALUES ('20160411140719'); - -INSERT INTO schema_migrations (version) VALUES ('20160414110443'); - -INSERT INTO schema_migrations (version) VALUES ('20160421074023'); - -INSERT INTO schema_migrations (version) VALUES ('20160429114732'); - -INSERT INTO schema_migrations (version) VALUES ('20160527110738'); - -INSERT INTO schema_migrations (version) VALUES ('20160629114503'); - -INSERT INTO schema_migrations (version) VALUES ('20161004101419'); - -INSERT INTO schema_migrations (version) VALUES ('20161227193500'); - -INSERT INTO schema_migrations (version) VALUES ('20170221115548'); - -INSERT INTO schema_migrations (version) VALUES ('20170419120048'); - -INSERT INTO schema_migrations (version) VALUES ('20170420125200'); - -INSERT INTO schema_migrations (version) VALUES ('20170422130054'); - -INSERT INTO schema_migrations (version) VALUES ('20170422142116'); - -INSERT INTO schema_migrations (version) VALUES ('20170422162824'); - -INSERT INTO schema_migrations (version) VALUES ('20170423151046'); - -INSERT INTO schema_migrations (version) VALUES ('20170423210622'); - -INSERT INTO schema_migrations (version) VALUES ('20170423214500'); - -INSERT INTO schema_migrations (version) VALUES ('20170423222302'); - -INSERT INTO schema_migrations (version) VALUES ('20170423225333'); - -INSERT INTO schema_migrations (version) VALUES ('20170424115801'); - -INSERT INTO schema_migrations (version) VALUES ('20170506144743'); - -INSERT INTO schema_migrations (version) VALUES ('20170506155009'); - -INSERT INTO schema_migrations (version) VALUES ('20170506162952'); - -INSERT INTO schema_migrations (version) VALUES ('20170506205356'); - -INSERT INTO schema_migrations (version) VALUES ('20170506205946'); - -INSERT INTO schema_migrations (version) VALUES ('20170506212014'); - -INSERT INTO schema_migrations (version) VALUES ('20170509215614'); - -INSERT INTO schema_migrations (version) VALUES ('20170604182521'); - -INSERT INTO schema_migrations (version) VALUES ('20170606133501'); - -INSERT INTO schema_migrations (version) VALUES ('20170606150352'); - -INSERT INTO schema_migrations (version) VALUES ('20170606202859'); - -INSERT INTO schema_migrations (version) VALUES ('20171009080822'); - -INSERT INTO schema_migrations (version) VALUES ('20171009082321'); - -INSERT INTO schema_migrations (version) VALUES ('20171025113808'); - -INSERT INTO schema_migrations (version) VALUES ('20171025153841'); - -INSERT INTO schema_migrations (version) VALUES ('20171121233843'); - -INSERT INTO schema_migrations (version) VALUES ('20171123035941'); - -INSERT INTO schema_migrations (version) VALUES ('20180112080312'); - -INSERT INTO schema_migrations (version) VALUES ('20180112084221'); - -INSERT INTO schema_migrations (version) VALUES ('20180112084442'); - -INSERT INTO schema_migrations (version) VALUES ('20180120172042'); - -INSERT INTO schema_migrations (version) VALUES ('20180120172649'); - -INSERT INTO schema_migrations (version) VALUES ('20180120172657'); - -INSERT INTO schema_migrations (version) VALUES ('20180120182712'); - -INSERT INTO schema_migrations (version) VALUES ('20180120183441'); - -INSERT INTO schema_migrations (version) VALUES ('20180121165304'); - -INSERT INTO schema_migrations (version) VALUES ('20180122105335'); - -INSERT INTO schema_migrations (version) VALUES ('20180123154407'); - -INSERT INTO schema_migrations (version) VALUES ('20180123165604'); - -INSERT INTO schema_migrations (version) VALUES ('20180123170112'); - -INSERT INTO schema_migrations (version) VALUES ('20180125092422'); - -INSERT INTO schema_migrations (version) VALUES ('20180126104536'); - -INSERT INTO schema_migrations (version) VALUES ('20180126104903'); - -INSERT INTO schema_migrations (version) VALUES ('20180129143538'); - -INSERT INTO schema_migrations (version) VALUES ('20180129232054'); - -INSERT INTO schema_migrations (version) VALUES ('20180129233223'); - -INSERT INTO schema_migrations (version) VALUES ('20180206213435'); - -INSERT INTO schema_migrations (version) VALUES ('20180206234620'); - -INSERT INTO schema_migrations (version) VALUES ('20180207071528'); - -INSERT INTO schema_migrations (version) VALUES ('20180207072139'); - -INSERT INTO schema_migrations (version) VALUES ('20180211011450'); - -INSERT INTO schema_migrations (version) VALUES ('20180211011948'); - -INSERT INTO schema_migrations (version) VALUES ('20180212123810'); - -INSERT INTO schema_migrations (version) VALUES ('20180212152810'); - -INSERT INTO schema_migrations (version) VALUES ('20180212154731'); - -INSERT INTO schema_migrations (version) VALUES ('20180213183818'); - -INSERT INTO schema_migrations (version) VALUES ('20180214200224'); - -INSERT INTO schema_migrations (version) VALUES ('20180214213743'); - -INSERT INTO schema_migrations (version) VALUES ('20180218004148'); - -INSERT INTO schema_migrations (version) VALUES ('20180228055259'); - -INSERT INTO schema_migrations (version) VALUES ('20180228064342'); - -INSERT INTO schema_migrations (version) VALUES ('20180228070102'); - -INSERT INTO schema_migrations (version) VALUES ('20180228070431'); - -INSERT INTO schema_migrations (version) VALUES ('20180228074442'); - -INSERT INTO schema_migrations (version) VALUES ('20180306180401'); - -INSERT INTO schema_migrations (version) VALUES ('20180306181538'); - -INSERT INTO schema_migrations (version) VALUES ('20180306181554'); - -INSERT INTO schema_migrations (version) VALUES ('20180306181911'); - -INSERT INTO schema_migrations (version) VALUES ('20180306182456'); - -INSERT INTO schema_migrations (version) VALUES ('20180306182758'); - -INSERT INTO schema_migrations (version) VALUES ('20180306182941'); - -INSERT INTO schema_migrations (version) VALUES ('20180306183540'); - -INSERT INTO schema_migrations (version) VALUES ('20180306183549'); - -INSERT INTO schema_migrations (version) VALUES ('20180308123240'); - -INSERT INTO schema_migrations (version) VALUES ('20180309053424'); - -INSERT INTO schema_migrations (version) VALUES ('20180309053921'); - -INSERT INTO schema_migrations (version) VALUES ('20180309054510'); - -INSERT INTO schema_migrations (version) VALUES ('20180310142630'); - -INSERT INTO schema_migrations (version) VALUES ('20180313090437'); - -INSERT INTO schema_migrations (version) VALUES ('20180313124751'); - -INSERT INTO schema_migrations (version) VALUES ('20180314122722'); - -INSERT INTO schema_migrations (version) VALUES ('20180327151906'); - -INSERT INTO schema_migrations (version) VALUES ('20180331200125'); - -INSERT INTO schema_migrations (version) VALUES ('20180422154642'); - -INSERT INTO schema_migrations (version) VALUES ('20180612042234'); - -INSERT INTO schema_migrations (version) VALUES ('20180612042625'); - -INSERT INTO schema_migrations (version) VALUES ('20180612042953'); - -INSERT INTO schema_migrations (version) VALUES ('20180613030330'); - -INSERT INTO schema_migrations (version) VALUES ('20180613045614'); - -INSERT INTO schema_migrations (version) VALUES ('20180713154915'); - -INSERT INTO schema_migrations (version) VALUES ('20180808064402'); - -INSERT INTO schema_migrations (version) VALUES ('20180816123540'); - -INSERT INTO schema_migrations (version) VALUES ('20180823161237'); - -INSERT INTO schema_migrations (version) VALUES ('20180823163548'); - -INSERT INTO schema_migrations (version) VALUES ('20180823174331'); - -INSERT INTO schema_migrations (version) VALUES ('20180823212823'); - -INSERT INTO schema_migrations (version) VALUES ('20180824092855'); - -INSERT INTO schema_migrations (version) VALUES ('20180824102834'); - -INSERT INTO schema_migrations (version) VALUES ('20180824215326'); - -INSERT INTO schema_migrations (version) VALUES ('20180825193437'); - -INSERT INTO schema_migrations (version) VALUES ('20180825232819'); - -INSERT INTO schema_migrations (version) VALUES ('20180826162821'); - -INSERT INTO schema_migrations (version) VALUES ('20181001090536'); - -INSERT INTO schema_migrations (version) VALUES ('20181002090319'); - -INSERT INTO schema_migrations (version) VALUES ('20181017092829'); - -INSERT INTO schema_migrations (version) VALUES ('20181017153658'); - -INSERT INTO schema_migrations (version) VALUES ('20181017153812'); - -INSERT INTO schema_migrations (version) VALUES ('20181017153935'); - -INSERT INTO schema_migrations (version) VALUES ('20181017154038'); - -INSERT INTO schema_migrations (version) VALUES ('20181017154143'); - -INSERT INTO schema_migrations (version) VALUES ('20181017205123'); - -INSERT INTO schema_migrations (version) VALUES ('20181022100114'); - -INSERT INTO schema_migrations (version) VALUES ('20181108154921'); - -INSERT INTO schema_migrations (version) VALUES ('20181129150515'); - -INSERT INTO schema_migrations (version) VALUES ('20181212105100'); - -INSERT INTO schema_migrations (version) VALUES ('20181212145456'); - -INSERT INTO schema_migrations (version) VALUES ('20181212145914'); - -INSERT INTO schema_migrations (version) VALUES ('20181213113115'); - -INSERT INTO schema_migrations (version) VALUES ('20181217144701'); - -INSERT INTO schema_migrations (version) VALUES ('20181217144845'); - -INSERT INTO schema_migrations (version) VALUES ('20181220094738'); - -INSERT INTO schema_migrations (version) VALUES ('20181220095053'); - -INSERT INTO schema_migrations (version) VALUES ('20181223153407'); - -INSERT INTO schema_migrations (version) VALUES ('20181226211337'); - -INSERT INTO schema_migrations (version) VALUES ('20181227155537'); - -INSERT INTO schema_migrations (version) VALUES ('20181227172042'); - -INSERT INTO schema_migrations (version) VALUES ('20181230231015'); - -INSERT INTO schema_migrations (version) VALUES ('20190102114702'); - -INSERT INTO schema_migrations (version) VALUES ('20190102115333'); - -INSERT INTO schema_migrations (version) VALUES ('20190102144032'); - -INSERT INTO schema_migrations (version) VALUES ('20190209150026'); - -INSERT INTO schema_migrations (version) VALUES ('20190302091059'); - -INSERT INTO schema_migrations (version) VALUES ('20190302111152'); - -INSERT INTO schema_migrations (version) VALUES ('20190311111718'); - -INSERT INTO schema_migrations (version) VALUES ('20190312211614'); - -INSERT INTO schema_migrations (version) VALUES ('20190315172802'); - -INSERT INTO schema_migrations (version) VALUES ('20190319133036'); - -INSERT INTO schema_migrations (version) VALUES ('20190322152123'); - -INSERT INTO schema_migrations (version) VALUES ('20190322152529'); - -INSERT INTO schema_migrations (version) VALUES ('20190328151516'); - -INSERT INTO schema_migrations (version) VALUES ('20190328151838'); - -INSERT INTO schema_migrations (version) VALUES ('20190404140234'); - -INSERT INTO schema_migrations (version) VALUES ('20190415120246'); - -INSERT INTO schema_migrations (version) VALUES ('20190426174225'); - -INSERT INTO schema_migrations (version) VALUES ('20190506100655'); - -INSERT INTO schema_migrations (version) VALUES ('20190510090240'); - -INSERT INTO schema_migrations (version) VALUES ('20190510102549'); - -INSERT INTO schema_migrations (version) VALUES ('20190515113153'); - -INSERT INTO schema_migrations (version) VALUES ('20190516161439'); - -INSERT INTO schema_migrations (version) VALUES ('20190520093231'); - -INSERT INTO schema_migrations (version) VALUES ('20190617120112'); - -INSERT INTO schema_migrations (version) VALUES ('20190617121716'); - -INSERT INTO schema_migrations (version) VALUES ('20190617121949'); - -INSERT INTO schema_migrations (version) VALUES ('20190617122505'); - -INSERT INTO schema_migrations (version) VALUES ('20190620084334'); diff --git a/db/whois_schema.rb b/db/whois_schema.rb index 7d3756dc1..9353bd80c 100644 --- a/db/whois_schema.rb +++ b/db/whois_schema.rb @@ -1,4 +1,3 @@ -# encoding: UTF-8 # This file is auto-generated from the current state of the database. Instead # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. @@ -11,41 +10,33 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20181102124618) do +ActiveRecord::Schema.define(version: 2018_11_02_124618) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" - create_table "ar_internal_metadata", primary_key: "key", force: :cascade do |t| - t.string "value" + create_table "contact_requests", force: :cascade do |t| + t.integer "whois_record_id", null: false + t.string "secret", null: false + t.string "email", null: false + t.string "name", null: false + t.datetime "valid_to", null: false + t.string "status", default: "new", null: false + t.inet "ip_address" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["email"], name: "index_contact_requests_on_email" + t.index ["ip_address"], name: "index_contact_requests_on_ip_address" + t.index ["secret"], name: "index_contact_requests_on_secret", unique: true + t.index ["whois_record_id"], name: "index_contact_requests_on_whois_record_id" end - create_table "contact_requests", id: :bigserial, force: :cascade do |t| - t.integer "whois_record_id", null: false - t.string "secret", null: false - t.string "email", null: false - t.string "name", null: false - t.datetime "valid_to", null: false - t.string "status", default: "new", null: false - t.inet "ip_address" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - - add_index "contact_requests", ["email"], name: "index_contact_requests_on_email", using: :btree - add_index "contact_requests", ["ip_address"], name: "index_contact_requests_on_ip_address", using: :btree - add_index "contact_requests", ["secret"], name: "index_contact_requests_on_secret", unique: true, using: :btree - add_index "contact_requests", ["whois_record_id"], name: "index_contact_requests_on_whois_record_id", using: :btree - create_table "whois_records", force: :cascade do |t| - t.string "name" - t.json "json" + t.string "name" + t.json "json" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["name"], name: "index_domains_on_name" end - add_index "whois_records", ["name"], name: "index_domains_on_name", using: :btree - end diff --git a/doc/application_build_doc.md b/doc/application_build_doc.md index 1f565d4d6..9b4ba9289 100644 --- a/doc/application_build_doc.md +++ b/doc/application_build_doc.md @@ -25,14 +25,14 @@ Deploy overview: (database schema should be loaded and seeds should be present) cd registry rbenv local 2.2.2 # more info about rbenv at debian doc gem install mina # or any other deployment tool - cp config/deploy-example.rb config/deploy.rb # and edit it + cp config/deploy.rb.sample config/deploy.rb # and edit it mina pr setup # one time, only creates missing directories ssh registry # at your server cd registry - cp current/config/application-example.yml shared/config/application.yml # and edit it - cp current/config/database-example.yml shared/config/database.yml # and edit it + cp current/config/application.yml.sample shared/config/application.yml # and edit it + cp current/config/database.yml.sample shared/config/database.yml # and edit it vi /etc/apache2/sites-enabled/registry.conf # add conf and all needed serts vi /etc/apache2/sites-enabled/epp.conf # add epp conf, restart apache @@ -48,7 +48,7 @@ We recommend [Mina](https://github.com/mina-deploy/mina) instead of Capistrano o All deploy code locates at config/deploy.rb, please copy content from example file and edit it. - cp config/deploy-example.rb config/deploy.rb # and edit it + cp config/deploy.rb.sample config/deploy.rb # and edit it First add shortcuts to your local machine ssh config file, @@ -117,13 +117,13 @@ General rake and mina tips: ### CRON -Crontab can be setup after deploy. Jobs can be viewed [here](/config/schedule.rb). Some jobs are dependent on `cron_group` variable set in [deploy-example.rb](/config/deploy-example.rb) file. +Crontab can be setup after deploy. Jobs can be viewed [here](/config/schedule.rb). Some jobs are dependent on `cron_group` variable set in [deploy.rb.sample](/config/deploy.rb.sample) file. mina pr cron:setup # to update the crontab. mina pr cron:clear # to clear crontab. ### Application settings -Application settings locate at [config/application-example.yml](/config/application-example.yml) +Application settings locate at [config/application.yml.sample](/config/application.yml.sample) diff --git a/doc/controllers_brief.svg b/doc/controllers_brief.svg index 63fc964ba..a33c36bb8 100644 --- a/doc/controllers_brief.svg +++ b/doc/controllers_brief.svg @@ -27,11 +27,6 @@ Epp::DomainsController - -Epp::KeyrelaysController - -Epp::KeyrelaysController - Epp::SessionsController @@ -87,11 +82,6 @@ Admin::ApiUsersController - -Admin::KeyrelaysController - -Admin::KeyrelaysController - Admin::SessionsController @@ -172,11 +162,6 @@ Registrar::DomainsController - -Registrar::KeyrelaysController - -Registrar::KeyrelaysController - Registrar::SessionsController @@ -247,10 +232,5 @@ Registrant::DomainDeleteConfirmsController - -EppController - -EppController - diff --git a/doc/controllers_complete.svg b/doc/controllers_complete.svg index 0501ceac9..892593e1a 100644 --- a/doc/controllers_complete.svg +++ b/doc/controllers_complete.svg @@ -54,18 +54,6 @@ validate_transfer validate_update - -Epp::KeyrelaysController - -Epp::KeyrelaysController - -keyrelay - - -_layout -find_domain -validate_keyrelay - Epp::SessionsController @@ -123,7 +111,6 @@ Epp::ErrorsController error -not_found _layout @@ -227,17 +214,6 @@ api_user_params set_api_user - -Admin::KeyrelaysController - -Admin::KeyrelaysController - -index -show - - -_layout - Admin::SessionsController @@ -459,17 +435,6 @@ init_contacts_autocomplete_map init_domain - -Registrar::KeyrelaysController - -Registrar::KeyrelaysController - -create -show - - -_layout - Registrar::SessionsController @@ -491,7 +456,6 @@ Registrar::PollsController -confirm_keyrelay confirm_transfer destroy show @@ -646,34 +610,5 @@ _layout - -EppController - -EppController - -create_full_selectors -current_user -element_count -epp_errors -epp_session -exactly_one_of -generate_svtrid -handle_errors -has_attribute -latin_only -mutually_exclusive -optional -optional_attribute -params_hash -render_epp_response -requires -requires_attribute -validate_request -write_to_epp_log -xml_attrs_present? - - -_layout - diff --git a/doc/debian_build_doc.md b/doc/debian_build_doc.md index ff619fd0a..2328c6d9b 100644 --- a/doc/debian_build_doc.md +++ b/doc/debian_build_doc.md @@ -7,7 +7,7 @@ however officially Debian 7 is supported and tested. ### Manual build * Consider using [RBENV](https://github.com/sstephenson/rbenv) -* Compile requried [ruby version](https://github.com/internetee/registry/blob/master/.ruby-version) +* Compile required [ruby version](https://github.com/internetee/registry/blob/master/.ruby-version) * [Phusion passenger](https://www.phusionpassenger.com/documentation/Users%20guide%20Apache.html) * [Postgresql](http://www.postgresql.org/docs/) (requires postgresql-contrib package) * [Mailcatcher](https://mailcatcher.me/) (optional) @@ -80,9 +80,9 @@ iptables -A INPUT -p tcp --dport 43 -m recent --set --rsource --name whois -j AC #### EPP -Configure epp server ip in applicatin.yml +Configure epp server ip in application.yml iptables_server_ip: 'x.x.x.x' -Iptables hitcounter is updated by application. For every registrar there is one recent table, where the request counters are stored, registrar handles and sources ips are "connected" with iptables rules. +Iptables hit counter is updated by application. For every registrar there is one recent table, where the request counters are stored, registrar handles and sources ips are "connected" with iptables rules. ```` #!/bin/bash @@ -99,8 +99,8 @@ iptables -A INPUT -p tcp --dport 700 -j CHKLIMITS ```` #### Mailcatcher for staging (optional) -We recommend using mailcatcher for staging env, so that all outgoing e-mails are caught and not actualy sent out. -The mailcatcher website explains how it should be intsalled and configured. +We recommend using mailcatcher for staging env, so that all outgoing e-mails are caught and not actually sent out. +The mailcatcher website explains how it should be installed and configured. [Mailcatcher](https://mailcatcher.me/) ````` diff --git a/doc/epp/README.md b/doc/epp/README.md index de4bcb8e8..23a581635 100644 --- a/doc/epp/README.md +++ b/doc/epp/README.md @@ -5,7 +5,6 @@ [Session related functions](session.md) [Contact related functions](contact.md) [Domain related functions](domain.md) -[Keyrelay related functions](keyrelay.md) ## Supported protocols @@ -25,7 +24,6 @@ * [epp-1.0.xsd](/lib/schemas/epp-1.0.xsd) * [eppcom-1.0.xsd](/lib/schemas/eppcom-1.0.xsd) * [host-1.0.xsd](/lib/schemas/host-1.0.xsd) -* [keyrelay-1.0.xsd](/lib/schemas/keyrelay-1.0.xsd) * [secDNS-1.1.xsd](/lib/schemas/secDNS-1.1.xsd) * [changePoll-1.0.xsd](/lib/schemas/changePoll-1.0.xsd) diff --git a/doc/epp/contact.md b/doc/epp/contact.md index 633e16cff..1aa49c2b5 100644 --- a/doc/epp/contact.md +++ b/doc/epp/contact.md @@ -31,7 +31,7 @@ More info: https://en.wikipedia.org/wiki/Latin_script_in_Unicode 0-1 State or province 0-1 Postal code 1 Country code, 2 letters uppercase, in ISO_3166-1 alpha 2 - 1 Phone number in format \+ddd.d+ + 1 Phone number in E.164 format (e.g. +372.12345) 0 Fax is not supported and must be blank or missing 1 E-mail 1 @@ -47,7 +47,7 @@ More info: https://en.wikipedia.org/wiki/Latin_script_in_Unicode Attribute: type="pdf/asice/sce/adoc/asics/scs/edoc/adoc/bdoc/ddoc/zip/rar/gz/tar/7z" 0-1 Client transaction id -[EXAMPLE REQUEST AND RESPONSE](/doc/epp-examples.md#epp-contact-with-valid-user-create-command-successfully-creates-a-contact) +[EXAMPLE REQUEST AND RESPONSE](/doc/epp_examples.md#epp-contact-with-valid-user-create-command-successfully-creates-a-contact) ### Contact update @@ -66,7 +66,7 @@ More info: https://en.wikipedia.org/wiki/Latin_script_in_Unicode 0-1 State or province 0-1 Postal code 1 Country code, 2 letters uppercase, in ISO_3166-1 alpha 2 - 0-1 Phone number in format \+ddd.d+ + 0-1 Phone number in E.164 format (e.g. +372.12345) 0 Fax is not supported and must be blank or missing 0-1 E-mail 0-1 Required if registrar is not the owner of the contact. @@ -85,7 +85,7 @@ More info: https://en.wikipedia.org/wiki/Latin_script_in_Unicode 0-1 Client transaction id -[EXAMPLE REQUEST AND RESPONSE](/doc/epp-examples.md#epp-contact-with-valid-user-update-command-is-succesful) +[EXAMPLE REQUEST AND RESPONSE](/doc/epp_examples.md#epp-contact-with-valid-user-update-command-is-succesful) ### Contact delete @@ -102,7 +102,7 @@ More info: https://en.wikipedia.org/wiki/Latin_script_in_Unicode Attribute: type="pdf/asice/sce/adoc/asics/scs/edoc/adoc/bdoc/ddoc/zip/rar/gz/tar/7z" 0-1 Client transaction id -[EXAMPLE REQUEST AND RESPONSE](/doc/epp-examples.md#epp-contact-with-valid-user-delete-command-deletes-contact) +[EXAMPLE REQUEST AND RESPONSE](/doc/epp_examples.md#epp-contact-with-valid-user-delete-command-deletes-contact) ### Contact check @@ -114,7 +114,7 @@ More info: https://en.wikipedia.org/wiki/Latin_script_in_Unicode 1-n Contact id 0-1 Client transaction id -[EXAMPLE REQUEST AND RESPONSE](/doc/epp-examples.md#epp-contact-with-valid-user-check-command-returns-info-about-contact-availability) +[EXAMPLE REQUEST AND RESPONSE](/doc/epp_examples.md#epp-contact-with-valid-user-check-command-returns-info-about-contact-availability) ### Contact info @@ -128,4 +128,4 @@ More info: https://en.wikipedia.org/wiki/Latin_script_in_Unicode 1 Contact password. Attribute: roid="String" 0-1 Client transaction id -[EXAMPLE REQUEST AND RESPONSE](/doc/epp-examples.md#epp-contact-with-valid-user-info-command-return-info-about-contact) +[EXAMPLE REQUEST AND RESPONSE](/doc/epp_examples.md#epp-contact-with-valid-user-info-command-return-info-about-contact) diff --git a/doc/epp/domain.md b/doc/epp/domain.md index df7611709..006cc00a6 100644 --- a/doc/epp/domain.md +++ b/doc/epp/domain.md @@ -45,7 +45,7 @@ Domain name mapping protocol short version: 0-1 Client transaction id -[EXAMPLE REQUEST AND RESPONSE](/doc/epp-examples.md#epp-domain-with-citizen-as-a-registrant-creates-a-domain) +[EXAMPLE REQUEST AND RESPONSE](/doc/epp_examples.md#epp-domain-with-citizen-as-a-registrant-creates-a-domain) ### Domain update @@ -95,7 +95,7 @@ Domain name mapping protocol short version: Attribute: type="pdf/asice/sce/adoc/asics/scs/edoc/adoc/bdoc/ddoc/zip/rar/gz/tar/7z" 0-1 Client transaction id -[EXAMPLE REQUEST AND RESPONSE](/doc/epp-examples.md#epp-domain-with-valid-domain-updates-domain-and-adds-objects) +[EXAMPLE REQUEST AND RESPONSE](/doc/epp_examples.md#epp-domain-with-valid-domain-updates-domain-and-adds-objects) ### Domain delete @@ -111,7 +111,7 @@ Domain name mapping protocol short version: Attribute: type="pdf/asice/sce/adoc/asics/scs/edoc/adoc/bdoc/ddoc/zip/rar/gz/tar/7z" 0-1 Client transaction id -[EXAMPLE REQUEST AND RESPONSE](/doc/epp-examples.md#epp-domain-with-valid-domain-deletes-domain) +[EXAMPLE REQUEST AND RESPONSE](/doc/epp_examples.md#epp-domain-with-valid-domain-deletes-domain) ### Domain info @@ -125,7 +125,7 @@ Domain name mapping protocol short version: 1 Domain transfer code. Attribute: roid="String" 0-1 Client transaction id -[EXAMPLE REQUEST AND RESPONSE](/doc/epp-examples.md#epp-domain-with-valid-domain-returns-domain-info) +[EXAMPLE REQUEST AND RESPONSE](/doc/epp_examples.md#epp-domain-with-valid-domain-returns-domain-info) ### Domain renew @@ -145,7 +145,7 @@ Domain name mapping protocol short version: Attribute: type="pdf/asice/sce/adoc/asics/scs/edoc/adoc/bdoc/ddoc/zip/rar/gz/tar/7z" 0-1 Client transaction id -[EXAMPLE REQUEST AND RESPONSE](/doc/epp-examples.md#epp-domain-with-valid-domain-renews-a-domain) +[EXAMPLE REQUEST AND RESPONSE](/doc/epp_examples.md#epp-domain-with-valid-domain-renews-a-domain) ### Domain transfer @@ -162,7 +162,7 @@ Domain name mapping protocol short version: Attribute: type="pdf/asice/sce/adoc/asics/scs/edoc/adoc/bdoc/ddoc/zip/rar/gz/tar/7z" 0-1 Client transaction id -[EXAMPLE REQUEST AND RESPONSE](/doc/epp-examples.md#epp-domain-with-valid-domain-transfers-a-domain) +[EXAMPLE REQUEST AND RESPONSE](/doc/epp_examples.md#epp-domain-with-valid-domain-transfers-a-domain) ### Domain check @@ -173,4 +173,4 @@ Domain name mapping protocol short version: 1 Domain name. Can contain unicode characters. 0-1 Client transaction id -[EXAMPLE REQUEST AND RESPONSE](/doc/epp-examples.md#epp-domain-with-valid-domain-checks-a-domain) +[EXAMPLE REQUEST AND RESPONSE](/doc/epp_examples.md#epp-domain-with-valid-domain-checks-a-domain) diff --git a/doc/epp/keyrelay.md b/doc/epp/keyrelay.md deleted file mode 100644 index cda7dfa56..000000000 --- a/doc/epp/keyrelay.md +++ /dev/null @@ -1,25 +0,0 @@ -## Keyrelay related functions - -### Keyrelay - -NB! Keyrelay not implemented. - - Field name Min-max Field description - --------------------- ------- ----------------- - 1 - 1 Domain name - 1 - 1 Allowed values: 0, 256, 257 - 1 Allowed values: 3 - 1 Allowed values: 3, 5, 6, 7, 8, 10, 13, 14 - 1 Public key - 1 - 1 Domain transfer code. Attribute: roid="String" - 1 - 0-1 Relative expiry duration (ISO8601). - Required if ext:absolute is not specified - 0-1 Absolute expiry date (ISO8601). - Required if ext:relative is not specified - 0-1 Client transaction id - -[EXAMPLE REQUEST AND RESPONSE](/doc/epp-examples.md#epp-keyrelay-makes-a-keyrelay-request) diff --git a/doc/epp/session.md b/doc/epp/session.md index 1e10dce2b..4f97a9095 100644 --- a/doc/epp/session.md +++ b/doc/epp/session.md @@ -8,7 +8,7 @@ Here are functions like login, logout, hello, poll -[EXAMPLE RESPONSE](/doc/epp-examples.md#epp-session-when-not-connected-greets-client-upon-connection) +[EXAMPLE RESPONSE](/doc/epp_examples.md#epp-session-when-not-connected-greets-client-upon-connection) ### Login request @@ -27,7 +27,7 @@ Here are functions like login, logout, hello, poll 0-n Extension URI that is going to be used in current connection. 0-1 Client transaction id -[EXAMPLE REQUEST AND RESPONSE](/doc/epp-examples.md#epp-session-when-connected-with-valid-user-logs-in-epp-user) +[EXAMPLE REQUEST AND RESPONSE](/doc/epp_examples.md#epp-session-when-connected-with-valid-user-logs-in-epp-user) ### Logout request @@ -36,7 +36,7 @@ Here are functions like login, logout, hello, poll 1 0-1 Client transaction id -[EXAMPLE REQUEST AND RESPONSE](/doc/epp-examples.md#epp-session-when-connected-with-valid-user-logs-out-epp-user) +[EXAMPLE REQUEST AND RESPONSE](/doc/epp_examples.md#epp-session-when-connected-with-valid-user-logs-out-epp-user) ### Poll request @@ -46,4 +46,4 @@ Here are functions like login, logout, hello, poll Attribute: op="req / ack" 0-1 Client transaction id -[EXAMPLE REQUEST AND RESPONSE](/doc/epp-examples.md#epp-poll-queues-and-dequeues-messages) +[EXAMPLE REQUEST AND RESPONSE](/doc/epp_examples.md#epp-poll-queues-and-dequeues-messages) diff --git a/doc/epp-examples.md b/doc/epp_examples.md similarity index 96% rename from doc/epp-examples.md rename to doc/epp_examples.md index 2ad383dfd..7e0e001ba 100644 --- a/doc/epp-examples.md +++ b/doc/epp_examples.md @@ -22,7 +22,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -1617,7 +1616,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -1717,7 +1715,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -1765,7 +1762,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -1849,7 +1845,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -2753,7 +2748,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -2841,7 +2835,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -2889,7 +2882,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -2968,7 +2960,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -3016,7 +3007,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -3104,7 +3094,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -3693,7 +3682,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -3805,7 +3793,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -3853,7 +3840,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -3935,7 +3921,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -3983,7 +3968,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -4078,7 +4062,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -4124,7 +4107,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -6839,7 +6821,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -6937,7 +6918,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -7059,7 +7039,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -7157,7 +7136,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -7203,7 +7181,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -7290,7 +7267,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -7338,7 +7314,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -7431,7 +7406,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -7479,7 +7453,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -7572,7 +7545,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -7620,7 +7592,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -7713,7 +7684,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -7761,7 +7731,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -7854,7 +7823,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -7902,7 +7870,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -7995,7 +7962,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -8043,7 +8009,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -8136,7 +8101,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -8184,7 +8148,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -8277,7 +8240,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -8325,7 +8287,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -8418,7 +8379,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -8466,7 +8426,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -8545,7 +8504,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -8647,7 +8605,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -8734,7 +8691,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -8834,7 +8790,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -8921,7 +8876,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -9093,7 +9047,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -9232,7 +9185,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -9399,7 +9351,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -9485,7 +9436,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -11279,7 +11229,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -11360,7 +11309,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -11991,7 +11939,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -12071,7 +12018,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -12119,7 +12065,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -12224,7 +12169,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -12272,7 +12216,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -12383,7 +12326,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -12844,7 +12786,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -12873,299 +12814,6 @@ RESPONSE: ``` -### EPP Keyrelay makes a keyrelay request - -REQUEST: - -```xml - - - - - domain67.ee - - 256 - 3 - 8 - cmlraXN0aGViZXN0 - - - 98oiewslkfkd - - - P1M13D - - - 1441791739 - - -``` - -RESPONSE: - -```xml - - - - - Unimplemented object service - - domain67.ee - - - - 1441791739 - ccReg-2567540489 - - - -``` - -### EPP Keyrelay returns an error when parameters are missing - -REQUEST: - -```xml - - - - - domain67.ee - - 3 - 8 - cmlraXN0aGViZXN0 - - - 98oiewslkfkd - - - Invalid Expiry - - - 1441791740 - - -``` - -RESPONSE: - -```xml - - - - - Required parameter missing: keyrelay > keyData > flags [flags] - - - Expiry relative must be compatible to ISO 8601 - - Invalid Expiry - - - - 1441791740 - ccReg-3316296442 - - - -``` - -### EPP Keyrelay returns an error on invalid relative expiry - -REQUEST: - -```xml - - - - - domain67.ee - - 256 - 3 - 8 - cmlraXN0aGViZXN0 - - - 98oiewslkfkd - - - Invalid Expiry - - - 1441791741 - - -``` - -RESPONSE: - -```xml - - - - - Expiry relative must be compatible to ISO 8601 - - Invalid Expiry - - - - 1441791741 - ccReg-5440105260 - - - -``` - -### EPP Keyrelay returns an error on invalid absolute expiry - -REQUEST: - -```xml - - - - - domain67.ee - - 256 - 3 - 8 - cmlraXN0aGViZXN0 - - - 98oiewslkfkd - - - Invalid Absolute - - - 1441791742 - - -``` - -RESPONSE: - -```xml - - - - - Expiry absolute must be compatible to ISO 8601 - - Invalid Absolute - - - - 1441791742 - ccReg-3004275558 - - - -``` - -### EPP Keyrelay saves legal document with keyrelay - -REQUEST: - -```xml - - - - - domain67.ee - - 256 - 3 - 8 - cmlraXN0aGViZXN0 - - - 98oiewslkfkd - - - P1D - - - - dGVzdCBmYWlsCg== - - 1441791743 - - -``` - -RESPONSE: - -```xml - - - - - Unimplemented object service - - domain67.ee - - - - 1441791743 - ccReg-5428813077 - - - -``` - -### EPP Keyrelay validates legal document types - -REQUEST: - -```xml - - - - - domain67.ee - - 256 - 3 - 8 - cmlraXN0aGViZXN0 - - - 98oiewslkfkd - - - P1D - - - - dGVzdCBmYWlsCg== - - 1441791744 - - -``` - -RESPONSE: - -```xml - - - - - Attribute is invalid: type - - - 1441791744 - ccReg-4758328068 - - - -``` - REQUEST: ```xml @@ -13183,7 +12831,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -13262,7 +12909,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -13337,7 +12983,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -13416,7 +13061,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -13494,7 +13138,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -13855,7 +13498,6 @@ RESPONSE: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -13901,7 +13543,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -13949,7 +13590,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -14032,7 +13672,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -14078,7 +13717,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -14126,7 +13764,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -14174,7 +13811,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -14220,7 +13856,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -14268,7 +13903,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -14346,7 +13980,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd @@ -14395,7 +14028,6 @@ REQUEST: https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 urn:ietf:params:xml:ns:secDNS-1.1 https://epp.tld.ee/schema/eis-1.0.xsd diff --git a/doc/models_brief.svg b/doc/models_brief.svg index 70a4579de..57012f0d5 100644 --- a/doc/models_brief.svg +++ b/doc/models_brief.svg @@ -161,17 +161,6 @@ - -KeyrelayVersion - -KeyrelayVersion - - -KeyrelayVersion->VersionAssociation - - - - AccountActivityVersion @@ -867,35 +856,6 @@ - -Keyrelay - -Keyrelay - - -Domain->Keyrelay - - - - - -Domain->Keyrelay - - - - - -Domain->Keyrelay - - - - - -Domain->Keyrelay - - - - Domain->LegalDocument @@ -1278,32 +1238,6 @@ - -Keyrelay->KeyrelayVersion - - - -versions - - -Keyrelay->KeyrelayVersion - - - -versions - - -Keyrelay->LegalDocument - - - - - -Keyrelay->LegalDocument - - - - WhiteIp->WhiteIpVersion diff --git a/doc/models_complete.svg b/doc/models_complete.svg index 644822637..c41283153 100644 --- a/doc/models_complete.svg +++ b/doc/models_complete.svg @@ -54,8 +54,6 @@ country_code :string registrar_id :integer active :boolean -csr :text -crt :text type :string registrant_ident :string encrypted_password :string @@ -314,28 +312,6 @@ - -KeyrelayVersion - -KeyrelayVersion - -id :integer -item_type :string -item_id :integer -event :string -whodunnit :string -object :json -object_changes :json -created_at :datetime -session :string -children :json - - -KeyrelayVersion->VersionAssociation - - - - AccountActivityVersion @@ -582,8 +558,6 @@ country_code :string registrar_id :integer active :boolean -csr :text -crt :text type :string registrant_ident :string encrypted_password :string @@ -1388,52 +1362,6 @@ - -Keyrelay - -Keyrelay - -id :integer -domain_id :integer -pa_date :datetime -key_data_flags :string -key_data_protocol :string -key_data_alg :string -key_data_public_key :text -auth_info_pw :string -expiry_relative :string -expiry_absolute :datetime -requester_id :integer -accepter_id :integer -created_at :datetime -updated_at :datetime -creator_str :string -updator_str :string - - -Domain->Keyrelay - - - - - -Domain->Keyrelay - - - - - -Domain->Keyrelay - - - - - -Domain->Keyrelay - - - - Domain->LegalDocument @@ -1733,8 +1661,6 @@ country_code :string registrar_id :integer active :boolean -csr :text -crt :text type :string registrant_ident :string encrypted_password :string @@ -2001,32 +1927,6 @@ - -Keyrelay->KeyrelayVersion - - - -versions - - -Keyrelay->KeyrelayVersion - - - -versions - - -Keyrelay->LegalDocument - - - - - -Keyrelay->LegalDocument - - - - WhiteIp->WhiteIpVersion @@ -2057,8 +1957,6 @@ country_code :string registrar_id :integer active :boolean -csr :text -crt :text type :string registrant_ident :string encrypted_password :string diff --git a/doc/que/README.md b/doc/que/README.md index e7d3032d0..1fd0ef664 100644 --- a/doc/que/README.md +++ b/doc/que/README.md @@ -16,7 +16,7 @@ In both serarious que requires working Registry deployment and full access to Re Installation at deployed server: cd /home/registry/registry/current - sudo cp doc/que/que-init-example /etc/init.d/que # and edit it + sudo cp doc/que/que_init_sample /etc/init.d/que # and edit it sudo chmod +x /etc/init.d/que sudo /etc/init.d/que # for help and other commands sudo /etc/init.d/que start # for manual start diff --git a/doc/que/que-init-example b/doc/que/que_init_sample similarity index 100% rename from doc/que/que-init-example rename to doc/que/que_init_sample diff --git a/doc/registrant-api/v1/domain.md b/doc/registrant-api/v1/domain.md index 5a5a61366..9163a2850 100644 --- a/doc/registrant-api/v1/domain.md +++ b/doc/registrant-api/v1/domain.md @@ -34,21 +34,25 @@ Content-Type: application/json "admin_contacts":[ { "name":"John Smith", - "id":"62015e7d-42c8-4d68-8164-e9b71680fd95" + "id":"62015e7d-42c8-4d68-8164-e9b71680fd95", + "email": "john@email.com" }, { "name":"William Smith", - "id":"a041c5b6-7772-4fac-83cd-fbce3b2c8867" + "id":"a041c5b6-7772-4fac-83cd-fbce3b2c8867", + "email": "william@email.com" } ], "tech_contacts":[ { "name":"John Smith", - "id":"62015e7d-42c8-4d68-8164-e9b71680fd95" + "id":"62015e7d-42c8-4d68-8164-e9b71680fd95", + "email": "john@email.com" }, { "name":"William Smith", "id":"a041c5b6-7772-4fac-83cd-fbce3b2c8867" + "email": "william@email.com" } ], "transfer_code":"98oiewslkfkd", @@ -60,9 +64,6 @@ Content-Type: application/json "period_unit":"y", "creator_str":null, "updator_str":null, - "legacy_id":null, - "legacy_registrar_id":null, - "legacy_registrant_id":null, "outzone_at":"2016-09-24T09:11:14.861Z", "delete_date":"2016-10-24", "registrant_verification_asked_at":null, @@ -96,6 +97,10 @@ Content-Type: application/json }, ], + "dnssec_keys": [ + "257 3 13 KlHFYV42UtxC7LpsolDpoUZ9DNPDRYQypalBRIqlubBg/zg78aqciLk+NaWUbrkN7AUaM7h7tx91sLN+ORVPxA==", + ], + "dnssec_changed_at": "2015-09-09T09:11:14.860Z", "status_notes":{ }, @@ -175,9 +180,6 @@ Content-Type: application/json "period_unit":"y", "creator_str":null, "updator_str":null, - "legacy_id":null, - "legacy_registrar_id":null, - "legacy_registrant_id":null, "outzone_at":"2016-09-24T09:11:14.861Z", "delete_date":"2016-10-24", "registrant_verification_asked_at":null, @@ -211,6 +213,10 @@ Content-Type: application/json }, ], + "dnssec_keys": [ + "257 3 13 KlHFYV42UtxC7LpsolDpoUZ9DNPDRYQypalBRIqlubBg/zg78aqciLk+NaWUbrkN7AUaM7h7tx91sLN+ORVPxA==", + ], + "dnssec_changed_at": "2015-09-09T09:11:14.860Z", "status_notes":{ }, @@ -282,9 +288,6 @@ Content-Type: application/json "period_unit":"y", "creator_str":null, "updator_str":null, - "legacy_id":null, - "legacy_registrar_id":null, - "legacy_registrant_id":null, "outzone_at":"2016-09-24T09:11:14.861Z", "delete_date":"2016-10-24", "registrant_verification_asked_at":null, @@ -317,6 +320,10 @@ Content-Type: application/json ] } ], + "dnssec_keys": [ + "257 3 13 KlHFYV42UtxC7LpsolDpoUZ9DNPDRYQypalBRIqlubBg/zg78aqciLk+NaWUbrkN7AUaM7h7tx91sLN+ORVPxA==", + ], + "dnssec_changed_at": "2015-09-09T09:11:14.860Z", "status_notes":{ }, diff --git a/doc/registrant-api/v1/registry_lock.md b/doc/registrant-api/v1/registry_lock.md index 61a2c0839..17f4c6f6e 100644 --- a/doc/registrant-api/v1/registry_lock.md +++ b/doc/registrant-api/v1/registry_lock.md @@ -60,9 +60,6 @@ Content-Type: application/json "period_unit":"y", "creator_str":null, "updator_str":null, - "legacy_id":null, - "legacy_registrar_id":null, - "legacy_registrant_id":null, "outzone_at":"2016-09-24T09:11:14.861Z", "delete_date":"2016-10-24", "registrant_verification_asked_at":null, @@ -204,9 +201,6 @@ Content-Type: application/json "period_unit":"y", "creator_str":null, "updator_str":null, - "legacy_id":null, - "legacy_registrar_id":null, - "legacy_registrant_id":null, "outzone_at":"2016-09-24T09:11:14.861Z", "delete_date":"2016-10-24", "registrant_verification_asked_at":null, diff --git a/doc/registrant-api.md b/doc/registrant_api.md similarity index 100% rename from doc/registrant-api.md rename to doc/registrant_api.md diff --git a/doc/repp/v1/auctions.md b/doc/repp/v1/auctions.md new file mode 100644 index 000000000..727e6712e --- /dev/null +++ b/doc/repp/v1/auctions.md @@ -0,0 +1,39 @@ +## GET /repp/v1/auctions + +Return a list of auctions currently in progress. The list of domains changes +every day. + +In contrast with other endpoints in REPP, this one is publicly available for +anyone without authentication. + +#### Request + +``` +GET /repp/v1/auctions HTTP/1.1 +Host: registry.test +User-Agent: curl/7.64.1 +Accept: */* +``` + +#### Response + +``` +HTTP/1.1 200 OK +Date: Thu, 21 May 2020 10:39:45 GMT +Content-Type: application/json; charset=utf-8 +ETag: W/"217bd9ee4dfbb332172a1baf80ee0ba9" +Cache-Control: max-age=0, private, must-revalidate +X-Request-Id: a26b6801-bf3f-4922-b0db-3b081bacb130 +X-Runtime: 1.481174 +Transfer-Encoding: chunked + +{ + "count":1, + "auctions": [ + { + "domain_name": "auctionäöüõ.test", + "punycode_domain_name": "xn--auction-cxa7mj0e.test" + } + ] +} +``` diff --git a/doc/repp/v1/contact.md b/doc/repp/v1/contact.md index 71bf6276d..41f45551f 100644 --- a/doc/repp/v1/contact.md +++ b/doc/repp/v1/contact.md @@ -50,7 +50,6 @@ Content-Type: application/json "zip": "11111", "country_code": "EE", "state": null, - "legacy_id": null, "statuses": [ "ok" ], diff --git a/doc/repp/v1/domain.md b/doc/repp/v1/domain.md index 035bb1e9a..c6734cbe2 100644 --- a/doc/repp/v1/domain.md +++ b/doc/repp/v1/domain.md @@ -48,9 +48,6 @@ Content-Type: application/json "period_unit": "y", "creator_str": null, "updator_str": null, - "legacy_id": null, - "legacy_registrar_id": null, - "legacy_registrant_id": null, "outzone_at": "2016-09-24T09:11:14.861Z", "delete_date": "2016-10-24", "registrant_verification_asked_at": null, diff --git a/doc/repp/v1/retained_domains.md b/doc/repp/v1/retained_domains.md new file mode 100644 index 000000000..7484ff8f2 --- /dev/null +++ b/doc/repp/v1/retained_domains.md @@ -0,0 +1,100 @@ +## GET /repp/v1/retained_domains + +Return a list of disputed, reserved and blocked domains, along with total count. +You can filter them by type of the domain, which can be: `reserved`, `blocked` +or `disputed`. + +NB! A domain name can be both `disputed` and `reserved` at the same time, and it +will appear on the list as two separate objects. + +In contrast with other endpoints in REPP, this one is publicly available for +anyone without authentication. + +#### Parameters + +| Field name | Required | Type | Allowed values | Description | +| ---------- | -------- | ---- | -------------- | ----------- | +| type | false | string | ["reserved", "blocked", "disputed"] | Type of domains to show | + + +#### Request + +``` +GET /repp/v1/retained_domains?type=reserved HTTP/1.1 +Accept: application/json +User-Agent: curl/7.64.1 +``` + +#### Response + +``` +HTTP/1.1 200 OK +Date: Fri, 15 May 2020 11:30:07 GMT +Content-Type: application/json; charset=utf-8 +ETag: W/"a905b531243a6b0be42beb9d6ce60619" +Cache-Control: max-age=0, private, must-revalidate +Transfer-Encoding: chunked + +{ + "count": 1, + "domains": [ + { + "name": "reserved.test", + "status": "reserved", + "punycode_name": "reserved.test" + } + ] +} +``` + +After you have made the first request, you can save the ETag header, and +send it as If-None-Match in the subsequent request for cache validation. +Due to the fact that the lists are not changing frequently and are quite long, +it is recommended that you take advantage of ETag cache. + +ETag key values depend on the request parameters. A request for only blocked +domains returns different cache key than request for all domains. + +### Cache Request + +``` +GET /repp/v1/retained_domains?type=reserved HTTP/1.1 +Accept: application/json +User-Agent: curl/7.64.1 +If-None-Match: W/"a905b531243a6b0be42beb9d6ce60619" +``` + +#### Cache hit response + +Response with no body and status 304 is sent in case the list have not changed. + +``` +HTTP/1.1 304 Not Modified +Date: Fri, 15 May 2020 11:34:25 GMT +ETag: W/"a905b531243a6b0be42beb9d6ce60619" +Cache-Control: max-age=0, private, must-revalidate +``` + +#### Cache miss response + +Standard 200 response (with the current complete list) is sent when the list have changed since last requested. + + +``` +HTTP/1.1 200 OK +Date: Fri, 15 May 2020 11:30:07 GMT +Content-Type: application/json; charset=utf-8 +ETag: W/"a905b531243a6b0be42beb9d6ce60619" +Transfer-Encoding: chunked + +{ + "count": 1, + "domains": [ + { + "name": "reserved.test", + "status": "reserved", + "punycode_name": "reserved.test" + } + ] +} +``` diff --git a/doc/repp-doc.md b/doc/repp_doc.md similarity index 62% rename from doc/repp-doc.md rename to doc/repp_doc.md index f01484fc3..1ffbf669c 100644 --- a/doc/repp-doc.md +++ b/doc/repp_doc.md @@ -1,7 +1,7 @@ # REPP integration specification -REPP uses HTTP/1.1 protocol (http://tools.ietf.org/html/rfc2616) and -Basic Authentication (http://tools.ietf.org/html/rfc2617#section-2) using +REPP uses HTTP/1.1 protocol (http://tools.ietf.org/html/rfc2616) and +Basic Authentication (http://tools.ietf.org/html/rfc2617#section-2) using Secure Transport (https://tools.ietf.org/html/rfc5246) with certificate and key (https://tools.ietf.org/html/rfc5280). Credentials and certificate are issued by EIS (in an exchange for desired API username, CSR and IP). @@ -10,13 +10,15 @@ To quickly test the API, use curl: curl -q -k --cert user.crt.pem --key user.key.pem https://TBA/repp/v1/accounts/balance -u username:password -Test API endpoint: https://testepp.internet.ee/repp/v1 +Test API endpoint: https://testepp.internet.ee/repp/v1 Production API endpoint: TBA Main communication specification through Restful EPP (REPP): -[Contact related functions](repp/v1/contact.md) -[Domain related functions](repp/v1/domain.md) -[Domain transfers](repp/v1/domain_transfers.md) -[Account related functions](repp/v1/account.md) -[Nameservers](repp/v1/nameservers.md) +[Contact related functions](repp/v1/contact.md) +[Domain related functions](repp/v1/domain.md) +[Domain transfers](repp/v1/domain_transfers.md) +[Account related functions](repp/v1/account.md) +[Nameservers](repp/v1/nameservers.md) +[Retained domains](repp/v1/retained_domains.md) +[Auctions](repp/v1/auctions.md) diff --git a/lib/action_controller/api.rb b/lib/action_controller/api.rb deleted file mode 100644 index 5a9fd4512..000000000 --- a/lib/action_controller/api.rb +++ /dev/null @@ -1,149 +0,0 @@ -# frozen_string_literal: true - -require "action_view" -require "action_controller" -require "action_controller/log_subscriber" - -module ActionController - # API Controller is a lightweight version of ActionController::Base, - # created for applications that don't require all functionalities that a complete - # \Rails controller provides, allowing you to create controllers with just the - # features that you need for API only applications. - # - # An API Controller is different from a normal controller in the sense that - # by default it doesn't include a number of features that are usually required - # by browser access only: layouts and templates rendering, cookies, sessions, - # flash, assets, and so on. This makes the entire controller stack thinner, - # suitable for API applications. It doesn't mean you won't have such - # features if you need them: they're all available for you to include in - # your application, they're just not part of the default API controller stack. - # - # Normally, +ApplicationController+ is the only controller that inherits from - # ActionController::API. All other controllers in turn inherit from - # +ApplicationController+. - # - # A sample controller could look like this: - # - # class PostsController < ApplicationController - # def index - # posts = Post.all - # render json: posts - # end - # end - # - # Request, response, and parameters objects all work the exact same way as - # ActionController::Base. - # - # == Renders - # - # The default API Controller stack includes all renderers, which means you - # can use render :json and brothers freely in your controllers. Keep - # in mind that templates are not going to be rendered, so you need to ensure - # your controller is calling either render or redirect_to in - # all actions, otherwise it will return 204 No Content. - # - # def show - # post = Post.find(params[:id]) - # render json: post - # end - # - # == Redirects - # - # Redirects are used to move from one action to another. You can use the - # redirect_to method in your controllers in the same way as in - # ActionController::Base. For example: - # - # def create - # redirect_to root_url and return if not_authorized? - # # do stuff here - # end - # - # == Adding New Behavior - # - # In some scenarios you may want to add back some functionality provided by - # ActionController::Base that is not present by default in - # ActionController::API, for instance MimeResponds. This - # module gives you the respond_to method. Adding it is quite simple, - # you just need to include the module in a specific controller or in - # +ApplicationController+ in case you want it available in your entire - # application: - # - # class ApplicationController < ActionController::API - # include ActionController::MimeResponds - # end - # - # class PostsController < ApplicationController - # def index - # posts = Post.all - # - # respond_to do |format| - # format.json { render json: posts } - # format.xml { render xml: posts } - # end - # end - # end - # - # Make sure to check the modules included in ActionController::Base - # if you want to use any other functionality that is not provided - # by ActionController::API out of the box. - class API < Metal - abstract! - - # Shortcut helper that returns all the ActionController::API modules except - # the ones passed as arguments: - # - # class MyAPIBaseController < ActionController::Metal - # ActionController::API.without_modules(:ForceSSL, :UrlFor).each do |left| - # include left - # end - # end - # - # This gives better control over what you want to exclude and makes it easier - # to create an API controller class, instead of listing the modules required - # manually. - def self.without_modules(*modules) - modules = modules.map do |m| - m.is_a?(Symbol) ? ActionController.const_get(m) : m - end - - MODULES - modules - end - - MODULES = [ - AbstractController::Rendering, - - UrlFor, - Redirecting, - ApiRendering, - Renderers::All, - ConditionalGet, - BasicImplicitRender, - StrongParameters, - - ForceSSL, - DataStreaming, - - # Before callbacks should also be executed as early as possible, so - # also include them at the bottom. - AbstractController::Callbacks, - - # Append rescue at the bottom to wrap as much as possible. - Rescue, - - # Add instrumentations hooks at the bottom, to ensure they instrument - # all the methods properly. - Instrumentation, - - # Params wrapper should come before instrumentation so they are - # properly showed in logs - ParamsWrapper - ] - - MODULES.each do |mod| - include mod - end - - ActiveSupport.run_load_hooks(:action_controller_api, self) - ActiveSupport.run_load_hooks(:action_controller, self) - end -end diff --git a/lib/action_controller/api/api_rendering.rb b/lib/action_controller/api/api_rendering.rb deleted file mode 100644 index 52e9f60fc..000000000 --- a/lib/action_controller/api/api_rendering.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -module ActionController - module ApiRendering - extend ActiveSupport::Concern - - included do - include Rendering - end - - def render_to_body(options = {}) - _process_options(options) - super - end - end -end \ No newline at end of file diff --git a/lib/action_controller/metal/basic_implicit_render.rb b/lib/action_controller/metal/basic_implicit_render.rb deleted file mode 100644 index 9030ea585..000000000 --- a/lib/action_controller/metal/basic_implicit_render.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -module ActionController - module BasicImplicitRender # :nodoc: - def send_action(method, *args) - super.tap { default_render unless performed? } - end - - def default_render(*args) - head :no_content - end - end -end \ No newline at end of file diff --git a/lib/core_ext/array.rb b/lib/core_monkey_patches/array.rb similarity index 100% rename from lib/core_ext/array.rb rename to lib/core_monkey_patches/array.rb diff --git a/lib/deserializers/xml/contact.rb b/lib/deserializers/xml/contact.rb new file mode 100644 index 000000000..4dd29c683 --- /dev/null +++ b/lib/deserializers/xml/contact.rb @@ -0,0 +1,61 @@ +module Deserializers + module Xml + class Contact + attr_reader :frame + + def initialize(frame) + @frame = frame + end + + def call + attributes = { + name: if_present('postalInfo name'), + org_name: if_present('postalInfo org'), + email: if_present('email'), + fax: if_present('fax'), + phone: if_present('voice'), + + # Address fields + city: if_present('postalInfo addr city'), + zip: if_present('postalInfo addr pc'), + street: if_present('postalInfo addr street'), + state: if_present('postalInfo addr sp'), + country_code: if_present('postalInfo addr cc'), + + # Auth info + auth_info: if_present('authInfo pw'), + + # statuses + statuses_to_add: statuses_to_add, + statuses_to_remove: statuses_to_remove, + } + + attributes.compact + end + + def if_present(css_path) + return if frame.css(css_path).blank? + + frame.css(css_path).text + end + + def statuses_to_add + statuses_frame = frame.css('add') + return if statuses_frame.blank? + + statuses_frame.css('status').map do |status| + status['s'] + end + end + + def statuses_to_remove + statuses_frame = frame.css('rem') + return if statuses_frame.blank? + + statuses_frame.css('status').map do |status| + status['s'] + end + end + end + end +end diff --git a/lib/deserializers/xml/contact_update.rb b/lib/deserializers/xml/contact_update.rb new file mode 100644 index 000000000..b3bc6fe4a --- /dev/null +++ b/lib/deserializers/xml/contact_update.rb @@ -0,0 +1,27 @@ +require 'deserializers/xml/legal_document' +require 'deserializers/xml/ident' +require 'deserializers/xml/contact' + +module Deserializers + module Xml + class ContactUpdate + attr_reader :frame + + def initialize(frame) + @frame = frame + end + + def contact + @contact ||= ::Deserializers::Xml::Contact.new(frame).call + end + + def ident + @ident ||= ::Deserializers::Xml::Ident.new(frame).call + end + + def legal_document + @legal_document ||= ::Deserializers::Xml::LegalDocument.new(frame).call + end + end + end +end diff --git a/lib/deserializers/xml/ident.rb b/lib/deserializers/xml/ident.rb new file mode 100644 index 000000000..0dc65cbb6 --- /dev/null +++ b/lib/deserializers/xml/ident.rb @@ -0,0 +1,34 @@ +module Deserializers + module Xml + class Ident + attr_reader :frame + + def initialize(frame) + @frame = frame.css('ident').first + end + + def call + if valid? + { + ident: frame.text, + ident_type: frame.attr('type'), + ident_country_code: frame.attr('cc'), + } + else + {} + end + end + + private + + def valid? + return false if frame.blank? + return false if frame.try('text').blank? + return false if frame.attr('type').blank? + return false if frame.attr('cc').blank? + + true + end + end + end +end diff --git a/lib/deserializers/xml/legal_document.rb b/lib/deserializers/xml/legal_document.rb new file mode 100644 index 000000000..b75267f2d --- /dev/null +++ b/lib/deserializers/xml/legal_document.rb @@ -0,0 +1,22 @@ +module Deserializers + module Xml + # Given a nokogiri frame, extract information about legal document from it. + class LegalDocument + attr_reader :frame + + def initialize(frame) + @frame = frame + end + + def call + ld = frame.css('legalDocument').first + return unless ld + + { + body: ld.text, + type: ld['type'], + } + end + end + end +end diff --git a/lib/epp_constraint.rb b/lib/epp_constraint.rb index c490254ed..1200a6075 100644 --- a/lib/epp_constraint.rb +++ b/lib/epp_constraint.rb @@ -15,7 +15,7 @@ class EppConstraint request.params[:nokogiri_frame] ||= Nokogiri::XML(request.params[:raw_frame] || request.params[:frame]) request.params[:parsed_frame] ||= request.params[:nokogiri_frame].dup.remove_namespaces! - unless [:keyrelay, :poll, :session, :not_found].include?(@type) + unless %i[poll session].include?(@type) element = "//#{@type}:#{request.params[:action]}" return false if request.params[:nokogiri_frame].xpath("#{element}", OBJECT_TYPES[@type]).none? end diff --git a/lib/gem_ext/builder.rb b/lib/gem_monkey_patches/builder.rb similarity index 100% rename from lib/gem_ext/builder.rb rename to lib/gem_monkey_patches/builder.rb diff --git a/lib/gem_ext/i18n.rb b/lib/gem_monkey_patches/i18n.rb similarity index 100% rename from lib/gem_ext/i18n.rb rename to lib/gem_monkey_patches/i18n.rb diff --git a/lib/gem_ext/paper_trail.rb b/lib/gem_monkey_patches/paper_trail.rb similarity index 69% rename from lib/gem_ext/paper_trail.rb rename to lib/gem_monkey_patches/paper_trail.rb index 12a8f0c3b..2edefa91b 100644 --- a/lib/gem_ext/paper_trail.rb +++ b/lib/gem_monkey_patches/paper_trail.rb @@ -1,9 +1,9 @@ # Store console and rake changes in versions if defined?(::Rails::Console) - PaperTrail.whodunnit = "console-#{`whoami`.strip}" + PaperTrail.request.whodunnit = "console-#{`whoami`.strip}" elsif File.basename($PROGRAM_NAME) == 'rake' # rake username does not work when spring enabled - PaperTrail.whodunnit = "rake-#{`whoami`.strip} #{ARGV.join ' '}" + PaperTrail.request.whodunnit = "rake-#{`whoami`.strip} #{ARGV.join ' '}" end class PaperSession diff --git a/config/initializers/eis_ransack.rb b/lib/gem_monkey_patches/ransack.rb similarity index 100% rename from config/initializers/eis_ransack.rb rename to lib/gem_monkey_patches/ransack.rb diff --git a/lib/rails5_api_controller_backport.rb b/lib/rails5_api_controller_backport.rb deleted file mode 100644 index 252332488..000000000 --- a/lib/rails5_api_controller_backport.rb +++ /dev/null @@ -1,3 +0,0 @@ -require_relative 'action_controller/metal/basic_implicit_render' -require_relative 'action_controller/api/api_rendering' -require_relative 'action_controller/api' \ No newline at end of file diff --git a/lib/schemas/all-ee-1.0.xsd b/lib/schemas/all-ee-1.0.xsd index 5cba9d965..d9ccffcfb 100644 --- a/lib/schemas/all-ee-1.0.xsd +++ b/lib/schemas/all-ee-1.0.xsd @@ -23,9 +23,6 @@ - - diff --git a/lib/schemas/all-ee-1.1.xsd b/lib/schemas/all-ee-1.1.xsd index 95c5185c4..c82fbc433 100644 --- a/lib/schemas/all-ee-1.1.xsd +++ b/lib/schemas/all-ee-1.1.xsd @@ -23,9 +23,6 @@ - - diff --git a/lib/schemas/keyrelay-1.0.xsd b/lib/schemas/keyrelay-1.0.xsd deleted file mode 100644 index d5a8335fd..000000000 --- a/lib/schemas/keyrelay-1.0.xsd +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - Extensible Provisioning Protocol v1.0 protocol - extension schema for relaying DNSSEC key material. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/lib/serializers/registrant_api/domain.rb b/lib/serializers/registrant_api/domain.rb index 500d6c08c..542f2d0de 100644 --- a/lib/serializers/registrant_api/domain.rb +++ b/lib/serializers/registrant_api/domain.rb @@ -32,9 +32,6 @@ module Serializers period_unit: domain.period_unit, creator_str: domain.creator_str, updator_str: domain.updator_str, - legacy_id: domain.legacy_id, - legacy_registrar_id: domain.legacy_registrar_id, - legacy_registrant_id: domain.legacy_registrant_id, outzone_at: domain.outzone_at, delete_date: domain.delete_date, registrant_verification_asked_at: domain.registrant_verification_asked_at, @@ -45,11 +42,23 @@ module Serializers locked_by_registrant_at: domain.locked_by_registrant_at, status_notes: domain.status_notes, nameservers: nameservers, + dnssec_keys: dnssec_keys, + dnssec_changed_at: dnssec_updated_at, } end private + def dnssec_keys + domain.dnskeys.map do |key| + "#{key.flags} #{key.protocol} #{key.alg} #{key.public_key}" + end + end + + def dnssec_updated_at + domain.dnskeys.order(updated_at: :desc).select(:updated_at).first + end + def contacts(type) contact_pool = begin if type == :tech @@ -61,7 +70,7 @@ module Serializers array_of_contacts = [] contact_pool.map do |contact| - array_of_contacts.push(name: contact.name, id: contact.uuid) + array_of_contacts.push(name: contact.name, id: contact.uuid, email: contact.email) end array_of_contacts diff --git a/lib/tasks/convert.rake b/lib/tasks/convert.rake deleted file mode 100644 index 47e0ec7c2..000000000 --- a/lib/tasks/convert.rake +++ /dev/null @@ -1,117 +0,0 @@ -namespace :convert do - desc 'Convert punycodes to unicode' - task punycode: :environment do - start = Time.zone.now.to_f - puts "-----> Convert domain punycodes to unicode..." - count = 0 - Domain.find_each(:batch_size => 1000) do |x| - old_name = x.name - if old_name != SimpleIDN.to_unicode(x.name.strip.downcase) - x.update_column(:name, (SimpleIDN.to_unicode(x.name.strip.downcase))) - x.update_column(:name_puny, (SimpleIDN.to_ascii(x.name.strip.downcase))) - count += 1 - puts "Domain #{x.id} changed from #{old_name} to #{SimpleIDN.to_unicode(old_name)} " - end - end - puts "-----> all done in #{(Time.zone.now.to_f - start).round(2)} seconds. #{count} domains changed." - end - - desc 'Convert punycodes in history to unicode' - task history_punycode: :environment do - DomainVersion.find_each do |d| - if obj = d.object - obj["name"] = SimpleIDN.to_unicode(obj["name"]) - obj["name_puny"] = SimpleIDN.to_ascii(obj["name_puny"]) - d.object = obj - end - if (obj_c = d.object_changes).present? - obj_c["name"].map!{|e| e ? SimpleIDN.to_unicode(e) : e } if obj_c["name"] - obj_c["name_puny"].map!{|e| e ? SimpleIDN.to_ascii(e) : e } if obj_c["name_puny"] - d.object_changes = obj_c - end - d.save! - end - end - - - desc 'Contact Address Country Code Upcase' - task country_code_upcase: :environment do - count = 0 - Contact.find_each do |c| - if c.country_code.present? && c.country_code != c.country_code.upcase - c.country_code = c.country_code.upcase - c.update_columns(country_code: c.country_code.upcase) - - count +=1 - puts "#{count} contacts has been changed" if count % 1000 == 0 - end - end - puts "Contacts change has been finished. Starting ContactVersions" - - count = 0 - ContactVersion.find_each do |c| - if (if_object = (c.object && c.object["country_code"].present? && c.object["country_code"] != c.object["country_code"].upcase)) || - (if_changes = (c.object_changes && c.object_changes["country_code"].present? && c.object_changes["country_code"] != c.object_changes["country_code"].map{|e|e.try(:upcase)})) - - if if_object - h = c.object - h["country_code"] = h["country_code"].try(:upcase) - c.object = h - end - - if if_changes - h = c.object_changes - h["country_code"] = h["country_code"].map{|e|e.try(:upcase)} - c.object_changes = h - end - c.update_columns(object: c.object, object_changes: c.object_changes) - - count +=1 - puts "#{count} contact histories has been changed" if count % 1000 == 0 - end - end - end - - desc 'Convert nameservers hostname and hostname_puny' - task nameserves_hostname: :environment do - - start = Time.zone.now.to_f - count = 0 - puts '-----> Converting hostnames...' - - Nameserver.find_each(:batch_size => 1000) do |ns| - ns.hostname = SimpleIDN.to_unicode(ns.hostname) - ns.hostname_puny = SimpleIDN.to_ascii(ns.hostname_puny) - ns.save validate: false - count += 1 - puts "-----> Converted #{count} nameservers" if count % 1000 == 0 - end - puts "-----> Converted #{count} nameservers #{(Time.zone.now.to_f - start).round(2)} seconds" - - end - - desc 'Convert nameservers history hostname' - task nameserves_history_hostname: :environment do - - start = Time.zone.now.to_f - count = 0 - puts '-----> Converting hostnames history...' - - NameserverVersion.find_each do |ns| - if obj = ns.object - obj["hostname"] = SimpleIDN.to_unicode(obj["hostname"]) - ns.object = obj - end - - if (obj_c = ns.object_changes).present? - obj_c["name"].map!{|e| e ? SimpleIDN.to_unicode(e) : e } if obj_c["hostname"] - ns.object_changes = obj_c - end - count += 1 - ns.save! - end - puts "-----> Converted #{count} history rows #{(Time.zone.now.to_f - start).round(2)} seconds" - end - -end - diff --git a/app/views/epp/contacts/_postal_info.xml.builder b/lib/tasks/data_migrations/.keep similarity index 100% rename from app/views/epp/contacts/_postal_info.xml.builder rename to lib/tasks/data_migrations/.keep diff --git a/lib/tasks/data_migrations/convert_domain_delete_date.rake b/lib/tasks/data_migrations/convert_domain_delete_date.rake deleted file mode 100644 index 7eeee5cf0..000000000 --- a/lib/tasks/data_migrations/convert_domain_delete_date.rake +++ /dev/null @@ -1,16 +0,0 @@ -namespace :data_migrations do - task convert_domain_delete_date: :environment do - processed_domain_count = 0 - - Domain.transaction do - Domain.find_each do |domain| - next unless domain.delete_date - - domain.update_columns(delete_date: domain.delete_date + 1.day) - processed_domain_count += 1 - end - end - - puts "Domains processed: #{processed_domain_count}" - end -end \ No newline at end of file diff --git a/lib/tasks/data_migrations/regenerate_registrar_reference_numbers.rake b/lib/tasks/data_migrations/regenerate_registrar_reference_numbers.rake deleted file mode 100644 index 6f6aaebe2..000000000 --- a/lib/tasks/data_migrations/regenerate_registrar_reference_numbers.rake +++ /dev/null @@ -1,16 +0,0 @@ -namespace :data_migrations do - task regenerate_registrar_reference_numbers: [:environment] do - processed_registrar_count = 0 - - Registrar.transaction do - Registrar.all.each do |registrar| - next unless registrar.reference_no.start_with?('RF') - - registrar.update_columns(reference_no: Billing::ReferenceNo.generate) - processed_registrar_count += 1 - end - end - - puts "Registrars processed: #{processed_registrar_count}" - end -end diff --git a/lib/tasks/dev/create_bank_transactions/bank_transactions.xml b/lib/tasks/dev/create_bank_transactions/bank_transactions.xml new file mode 100644 index 000000000..72a53b697 --- /dev/null +++ b/lib/tasks/dev/create_bank_transactions/bank_transactions.xml @@ -0,0 +1,73 @@ + + + + + populated by rake task + 2019-07-28T10:00:00 + 1 + + 0.1 + + ABC Corporation + + + + test3 + TRF + false + 1 + 2019-07-28 + + test + + + + populated by rake task + + EUR + + + + LHVBEE22 + + + + + ABC/090928/CCT001/01 + ABC/4562/2009-09-08 + + + + 0.1 + + SHAR + + + LHVBEE22 + + + + DEF Electronics + + Corn Exchange 5th Floor + + + + + populated by rake task + + + + + 1 + + + + 13 + + + + + + + diff --git a/lib/tasks/dev/create_bank_transactions/create_bank_transactions.rake b/lib/tasks/dev/create_bank_transactions/create_bank_transactions.rake new file mode 100644 index 000000000..17b7586e2 --- /dev/null +++ b/lib/tasks/dev/create_bank_transactions/create_bank_transactions.rake @@ -0,0 +1,38 @@ +namespace :dev do + task create_bank_transactions: :environment do + remitter_iban = ENV['remitter_iban'] + beneficiary_iban = Setting.registry_iban + + keystore = OpenSSL::PKCS12.new(File.read(ENV['lhv_p12_keystore']), ENV['lhv_keystore_password']) + key = keystore.key + cert = keystore.certificate + + api_base_uri = URI.parse('https://testconnect.lhv.eu/connect-prelive') + request_headers = { 'content-type' => 'application/xml' } + + request_xml = File.binread(File.join(__dir__, 'bank_transactions.xml')) + request_xml_doc = Nokogiri::XML(request_xml) + request_xml_doc.at_css('CstmrCdtTrfInitn > GrpHdr > MsgId').content = SecureRandom.hex + request_xml_doc.at_css('CstmrCdtTrfInitn > PmtInf > DbtrAcct > Id > IBAN') + .content = remitter_iban + request_xml_doc.at_css('CstmrCdtTrfInitn > PmtInf > CdtTrfTxInf > CdtrAcct > Id > IBAN') + .content = beneficiary_iban + request_body = request_xml_doc.to_xml + + http = Net::HTTP.new(api_base_uri.host, api_base_uri.port) + http.use_ssl = api_base_uri.is_a?(URI::HTTPS) + http.cert = cert + http.key = key + http.ca_file = ENV['lhv_ca_file'] + + http.start do + response = http.post(api_base_uri.path + '/payment', request_body, request_headers) + + if response.is_a?(Net::HTTPSuccess) + puts 'Success' + else + puts 'Failure' + end + end + end +end diff --git a/lib/tasks/import.rake b/lib/tasks/import.rake deleted file mode 100644 index ebd40a65e..000000000 --- a/lib/tasks/import.rake +++ /dev/null @@ -1,783 +0,0 @@ -namespace :import do - # README - # - # 1) ESTABLISH CONNECTION TO FRED DATABASE - # ---------------------------------------- - # - # Add 'fred' database connection settings to config/database.yml - # Example config: - # - # fred: - # host: localhost - # adapter: postgresql - # encoding: unicode - # pool: 5 - # username: fred - # password: fred - # - # Verify you have correctly connected to fred database: - # Open Rails console: - # - # cd your_registry_deploy_path/current/ - # RAILS_ENV=production bundle exec rails c - # in console: Legacy::Contact.last - # in console: exit - # - # In console you should get Last Legacy::Contact object. - # If you get any errors, scroll up and read first lines - # to figure out what went wrong to connect to fred database. - # - # - # 2) START IMPORT - # --------------- - # - # Import scrip does not write anything to fred database. - # Script is implemented this way, you can run it multiple times - # in case you need it. However already imported object are - # not reimported, thus if some object has been updated meanwhile - # in fred database, those updates will be missed and thous should - # be carried over manually. All new object in fred will be - # imported in multiple import script runs. - # - # Start all import: - # - # cd your_registry_deploy_path/current/ - # RAILS_ENV=production bundle exec rails import:all - # - # If you wish to import one by one, please follow individual import order - # from task 'Import all' tasks in this script. - - desc 'Import all' - task all: :environment do - Rake::Task['import:registrars'].invoke - Rake::Task['import:users'].invoke - Rake::Task['import:contacts'].invoke - Rake::Task['import:reserved'].invoke - Rake::Task['import:domains'].invoke - Rake::Task['import:zones'].invoke - end - - desc 'Import registrars' - task registrars: :environment do - start = Time.zone.now.to_f - puts '-----> Importing registrars...' - - registrars = [] - existing_ids = Registrar.pluck(:legacy_id) - user = "rake-#{`whoami`.strip} #{ARGV.join ' '}" - count = 0 - - Legacy::Registrar.all.each do |x| - next if existing_ids.include?(x.id) - count += 1 - - registrars << Registrar.new({ - name: x.organization.try(:strip).presence || x.name.try(:strip).presence || x.handle.try(:strip).presence, - reg_no: x.ico.try(:strip), - vat_no: x.dic.try(:strip), - phone: x.telephone.try(:strip), - email: x.email.try(:strip), - billing_email: x.billing_address.try(:strip), - country_code: x.country.try(:strip), - state: x.stateorprovince.try(:strip), - city: x.city.try(:strip), - street: x.street1.try(:strip), - zip: x.postalcode.try(:strip), - url: x.url.try(:strip), - accounting_customer_code: x.directo_handle.try(:strip), - legacy_id: x.id, - creator_str: user, - updator_str: user, - code: x.handle.upcase - }) - end - - Registrar.import registrars, validate: false - - puts "-----> Generating reference numbers" - - Registrar.all.each do |x| - x.save(validate: false) - end - - puts "-----> Creating accounts numbers" - - Registrar.all.each do |x| - next if x.cash_account - x.accounts.create(account_type: Account::CASH, currency: 'EUR') - x.save(validate: false) - - lr = Legacy::Registrar.find(x.legacy_id) - x.cash_account.account_activities << AccountActivity.new({ - sum: lr.account_balance, - currency: 'EUR', - description: 'Transfer from legacy system' - }) - - x.cash_account.save - end - - puts "-----> Imported #{count} new registrars in #{(Time.zone.now.to_f - start).round(2)} seconds" - end - - desc 'Import users' - task users: :environment do - start = Time.zone.now.to_f - puts "-----> Importing users and IP's..." - - id_users = [] - users = [] - ips = [] - temp = [] - - existing_ids = ApiUser.pluck(:legacy_id) - existing_ips = WhiteIp.pluck(:ipv4) - - Legacy::Registrar.all.each do |x| - - x.acl.all.each do |y| - - next if existing_ids.include?(y.id) - - if y.try(:cert) != 'pki' - - if y.try(:cert) == 'idkaart' - id_users << ApiUser.new({ - username: y.try(:password) ? y.try(:password) : y.try(:password), - plain_text_password: ('a'..'z').to_a.shuffle.first(8).join, - identity_code: y.try(:password) ? y.try(:password) : y.try(:password), - registrar_id: Registrar.find_by(legacy_id: x.try(:id)).try(:id), - roles: ['billing'], - legacy_id: y.try(:id) - }) - else - temp << ApiUser.new({ - username: x.handle.try(:strip), - plain_text_password: y.try(:password) ? y.try(:password) : ('a'..'z').to_a.shuffle.first(8).join, - registrar_id: Registrar.find_by(legacy_id: x.try(:id)).try(:id), - roles: ['epp'], - legacy_id: y.try(:id) - }) - end - end - temp = temp.reverse!.uniq{|u| u.username } - end - users = temp - - x.acl.all.each do |y| - next if existing_ips.include?(y.ipaddr) - if !y.ipaddr.nil? && y.ipaddr != '' - - y.ipaddr.split(',').each do |ip| - ips << WhiteIp.new({ - registrar_id: Registrar.find_by(legacy_id: x.try(:id)).try(:id), - ipv4: ip, - interfaces: ['api', 'registrar'] - }) - - end - end - end - end - - ApiUser.import id_users, validate: false - ApiUser.import users, validate: false - - if ips - WhiteIp.import ips, validate: false - end - - puts "-----> Imported #{id_users.count} billing users and #{users.count} epp users" - puts "-----> Imported #{ips.count} white IP's in #{(Time.zone.now.to_f - start).round(2)} seconds" - - end - - desc 'Import contacts' - task contacts: :environment do - start = Time.zone.now.to_f - puts '-----> Importing contacts...' - - # 1;"RC";"born number" # not used - # 2;"OP";"identity card number" -> priv - # 3;"PASS";"passwport" -> - # 4;"ICO";"organization identification number" - # 5;"MPSV";"social system identification" # not used - # 6;"BIRTHDAY";"day of birth" - - ident_type_map = { - 2 => Contact::PRIV, - 3 => Contact::PASSPORT, - 4 => Contact::ORG, - 6 => Contact::BIRTHDAY - } - - contact_columns = %w( - code - phone - email - fax - created_at - updated_at - ident - ident_type - auth_info - name - registrar_id - creator_str - updator_str - legacy_id - street - city - zip - state - country_code - statuses - ) - - contacts = [] - existing_contact_ids = Contact.pluck(:legacy_id) - count = 0 - - Legacy::Contact.includes(:object_registry, :object, object_registry: :registrar) - .find_each(batch_size: 10000).with_index do |x, index| - - next if existing_contact_ids.include?(x.id) - count += 1 - - if 4 == x.ssntype - name = x.organization.try(:strip).presence || x.name.try(:strip).presence - else - name = x.name.try(:strip).presence || x.organization.try(:strip).presence - end - - begin - contacts << [ - x.object_registry.name.try(:strip), - x.telephone.try(:strip), - [x.email.try(:strip), x.notifyemail.try(:strip)].uniq.select(&:present?).join(', '), - x.fax.try(:strip), - x.object_registry.try(:crdate), - x.object.read_attribute(:update).nil? ? x.object_registry.try(:crdate) : x.object.read_attribute(:update), - x.ssn.try(:strip), - ident_type_map[x.ssntype], - x.object.authinfopw.try(:strip), - name, - Registrar.find_by(legacy_id: x.object.try(:clid)).try(:id), - x.object_registry.try(:registrar).try(:name), - x.object.try(:registrar).try(:name) ? x.object.try(:registrar).try(:name) : x.object_registry.try(:registrar).try(:name), - x.id, - [x.street1.try(:strip), x.street2.try(:strip), x.street3.try(:strip)].compact.join(", "), - x.city.try(:strip), - x.postalcode.try(:strip), - x.stateorprovince.try(:strip), - x.country.try(:strip), - [x.object_state.try(:name), Contact::OK].compact - ] - - if contacts.size % 10000 == 0 - Contact.import contact_columns, contacts, {validate: false, timestamps: false} - contacts = [] - end - rescue => e - puts "ERROR on index #{index}" - puts e - end - end - - Contact.import contact_columns, contacts, {validate: false, timestamps: false} - puts "-----> Imported #{count} new contacts in #{(Time.zone.now.to_f - start).round(2)} seconds" - end - - desc 'Import reserved' - task reserved: :environment do - start = Time.zone.now.to_f - puts '-----> Importing reserved domains...' - - reserved_domains = [] - count = 0 - - existing_ids = ReservedDomain.pluck(:legacy_id) - - Legacy::Domain.includes( - :object_registry, - :object - ).find_each(batch_size: 1000).with_index do |x, index| - - next if existing_ids.include?(x.id) || Registrar.find_by(legacy_id: x.object.try(:clid)).try(:name) != 'eedirect' - count += 1 - - reserved_domains << ReservedDomain.new({ - created_at: x.object_registry.try(:crdate), - updated_at: x.object.read_attribute(:update).nil? ? x.object_registry.try(:crdate) : x.object.read_attribute(:update), - creator_str: x.object_registry.try(:registrar).try(:name), - updator_str: x.object.try(:registrar).try(:name) ? x.object.try(:registrar).try(:name) : x.object_registry.try(:registrar).try(:name), - names: '"' + x.object_registry.name.try(:strip) + '"=>"' + SecureRandom.hex + '"', - legacy_id: x.id - }) - - if index % 1000 == 0 && index != 0 - ReservedDomain.import reserved_domains, {validate: false, timestamps: false} - reserved_domains = [] - end - end - ReservedDomain.import reserved_domains, {validate: false, timestamps: false} - puts "-----> Imported #{count} new reserved domains in #{(Time.zone.now.to_f - start).round(2)} seconds" - end - - desc 'Import domains' - task domains: :environment do - start = Time.zone.now.to_f - puts '-----> Importing domains...' - - domain_columns = %w( - name - registrar_id - registered_at - valid_to - transfer_code - created_at - updated_at - name_dirty - name_puny - period - period_unit - creator_str - updator_str - legacy_id - legacy_registrar_id - legacy_registrant_id - statuses - ) - - domain_contact_columns = %w( - type - creator_str - updator_str - legacy_domain_id - legacy_contact_id - ) - - domain_status_columns = %w( - description - value - creator_str - updator_str - legacy_domain_id - ) - - nameserver_columns = %w( - hostname - ipv4 - ipv6 - creator_str - updator_str - legacy_domain_id - created_at - updated_at - ) - - dnskey_columns = %w( - flags - protocol - alg - public_key - creator_str - updator_str - legacy_domain_id - updated_at - ) - - domains, nameservers, dnskeys, domain_contacts = [], [], [], [] - existing_domain_ids = Domain.pluck(:legacy_id) - user = "rake-#{`whoami`.strip} #{ARGV.join ' '}" - count = 0 - - Legacy::Domain.includes( - :object_registry, - :object, - :nsset, - :object_states, - :dnskeys, - :domain_contact_maps, - nsset: { hosts: :host_ipaddr_maps } - ).find_each(batch_size: 10000).with_index do |x, index| - next if existing_domain_ids.include?(x.id) || Registrar.find_by(legacy_id: x.object.try(:clid)).try(:name) == 'eedirect' - count += 1 - - begin - # domain statuses - domain_statuses = [] - x.object_states.each do |state| - next if state.name.blank? - domain_statuses << state.name - end - - # OK status is default - domain_statuses << DomainStatus::OK if domain_statuses.empty? - - domains << [ - x.object_registry.name.try(:strip), - Registrar.find_by(legacy_id: x.object.try(:clid)).try(:id), - x.object_registry.try(:crdate), - x.object_registry.try(:crdate), - x.exdate, - x.object.authinfopw.try(:strip), - x.object_registry.try(:crdate), - x.object.read_attribute(:update).nil? ? x.object_registry.try(:crdate) : x.object.read_attribute(:update), - x.object_registry.name.try(:strip), - SimpleIDN.to_ascii(x.object_registry.name.try(:strip)), - 1, - 'y', - x.object_registry.try(:registrar).try(:name), - x.object.try(:registrar).try(:name) ? x.object.try(:registrar).try(:name) : x.object_registry.try(:registrar).try(:name), - x.id, - x.object_registry.try(:crid), - x.registrant, - domain_statuses - ] - - # admin contacts - x.domain_contact_maps.each do |dc| - domain_contacts << [ - 'AdminDomainContact', - x.object_registry.try(:registrar).try(:name), - x.object.try(:registrar).try(:name) ? x.object.try(:registrar).try(:name) : x.object_registry.try(:registrar).try(:name), - x.id, - dc.contactid - ] - end - - # tech contacts - x.nsset_contact_maps.each do |dc| - domain_contacts << [ - 'TechDomainContact', - x.object_registry.try(:registrar).try(:name), - x.object.try(:registrar).try(:name) ? x.object.try(:registrar).try(:name) : x.object_registry.try(:registrar).try(:name), - x.id, - dc.contactid - ] - end - - # nameservers - nsset = x.nsset - nsset.hosts.each do |host| - ip_maps = host.host_ipaddr_maps - ips = { - ipv4: [], - ipv6: [], - } - ip_maps.each do |ip_map| - next unless ip_map.ipaddr - ips[:ipv4] << ip_map.ipaddr.to_s.strip if ip_map.ipaddr.ipv4? - ips[:ipv6] << ip_map.ipaddr.to_s.strip if ip_map.ipaddr.ipv6? - end - - nameservers << [ - host.fqdn.try(:strip), - ips[:ipv4], - ips[:ipv6], - x.object_registry.try(:registrar).try(:name), - x.object.try(:registrar).try(:name) ? x.object.try(:registrar).try(:name) : x.object_registry.try(:registrar).try(:name), - x.id, - nsset.object_registry.try(:crdate), - nsset.object_registry.try(:object_history).read_attribute(:update).nil? ? nsset.object_registry.try(:crdate) : nsset.object_registry.try(:object_history).read_attribute(:update) - ] - end if x.nsset && x.nsset.hosts - - x.dnskeys.each do |key| - dnskeys << [ - key.flags, - key.protocol, - key.alg, - key.key, - x.object_registry.try(:registrar).try(:name), - x.object.try(:registrar).try(:name) ? x.object.try(:registrar).try(:name) : x.object_registry.try(:registrar).try(:name), - x.id, - key.object_registry.try(:object_history).read_attribute(:update).nil? ? key.try(:crdate)||Time.zone.now : key.object_registry.try(:object_history).read_attribute(:update) - ] - end - - if index % 10000 == 0 && index != 0 - Domain.import domain_columns, domains, {validate: false, timestamps: false} - Nameserver.import nameserver_columns, nameservers, {validate: false, timestamps: false} - Dnskey.import dnskey_columns, dnskeys, {validate: false, timestamps: false} - DomainContact.import domain_contact_columns, domain_contacts, validate: false # created_at is taken from contact at the bottom - domains, nameservers, dnskeys, domain_contacts = [], [], [], [] - end - rescue => e - puts "ERROR on index #{index}" - puts e - end - end - - Domain.import domain_columns, domains, {validate: false, timestamps: false} - Nameserver.import nameserver_columns, nameservers, {validate: false, timestamps: false} - Dnskey.import dnskey_columns, dnskeys, {validate: false, timestamps: false} - DomainContact.import domain_contact_columns, domain_contacts, validate: false - - puts '-----> Updating relations...' - - # registrant - ActiveRecord::Base.connection.execute( - "UPDATE domains "\ - "SET registrant_id = contacts.id "\ - "FROM contacts "\ - "WHERE contacts.legacy_id = legacy_registrant_id "\ - "AND legacy_registrant_id IS NOT NULL "\ - "AND registrant_id IS NULL" - ) - - # registrar - ActiveRecord::Base.connection.execute( - "UPDATE domains "\ - "SET registrar_id = registrars.id "\ - "FROM registrars "\ - "WHERE registrars.legacy_id = legacy_registrar_id "\ - "AND legacy_registrar_id IS NOT NULL "\ - "AND registrar_id IS NULL" - ) - - # contacts - ActiveRecord::Base.connection.execute( - "UPDATE domain_contacts "\ - "SET contact_id = contacts.id, "\ - "updated_at = contacts.updated_at, "\ - "created_at = contacts.created_at "\ - "FROM contacts "\ - "WHERE contacts.legacy_id = legacy_contact_id "\ - "AND legacy_contact_id IS NOT NULL "\ - "AND contact_id IS NULL" - ) - - ActiveRecord::Base.connection.execute( - "UPDATE domain_contacts "\ - "SET domain_id = domains.id "\ - "FROM domains "\ - "WHERE domains.legacy_id = legacy_domain_id "\ - "AND legacy_domain_id IS NOT NULL "\ - "AND domain_id IS NULL" - ) - - # nameservers - ActiveRecord::Base.connection.execute( - "UPDATE nameservers "\ - "SET domain_id = domains.id "\ - "FROM domains "\ - "WHERE domains.legacy_id = legacy_domain_id "\ - "AND legacy_domain_id IS NOT NULL "\ - "AND domain_id IS NULL" - ) - - # dnskeys - ActiveRecord::Base.connection.execute( - "UPDATE dnskeys "\ - "SET domain_id = domains.id "\ - "FROM domains "\ - "WHERE domains.legacy_id = legacy_domain_id "\ - "AND legacy_domain_id IS NOT NULL "\ - "AND domain_id IS NULL" - ) - - puts '-----> Generating dnskey digests...' - - Dnskey.all.each do |ds| - ds.generate_digest - ds.generate_ds_key_tag - ds.save(validate: false) - end - - puts "-----> Imported #{count} new domains in #{(Time.zone.now.to_f - start).round(2)} seconds" - end - - desc 'Import zones' - task zones: :environment do - start = Time.zone.now.to_f - puts '-----> Importing zones...' - - ns_records, a_records, a4_records = parse_zone_ns_data('ee', 1) - - DNS::Zone.create!({ - origin: 'ee', - ttl: 43200, - refresh: 3600, - retry: 900, - expire: 1209600, - minimum_ttl: 3600, - email: 'hostmaster.eestiinternet.ee', - master_nameserver: 'ns.tld.ee', - ns_records: ns_records, - a_records: a_records, - a4_records: a4_records - }) - - # edu.ee - ns_records, a_records, a4_records = parse_zone_ns_data('edu.ee', 6) - - DNS::Zone.create!({ - origin: 'edu.ee', - ttl: 43200, - refresh: 3600, - retry: 900, - expire: 1209600, - minimum_ttl: 3600, - email: 'hostmaster.eestiinternet.ee', - master_nameserver: 'ns.tld.ee', - ns_records: ns_records, - a_records: a_records, - a4_records: a4_records - }) - - # aip.ee - ns_records, a_records, a4_records = parse_zone_ns_data('aip.ee', 9) - - DNS::Zone.create!({ - origin: 'aip.ee', - ttl: 43200, - refresh: 3600, - retry: 900, - expire: 1209600, - minimum_ttl: 3600, - email: 'hostmaster.eestiinternet.ee', - master_nameserver: 'ns.tld.ee', - ns_records: ns_records, - a_records: a_records, - a4_records: a4_records - }) - - # org.ee - ns_records, a_records, a4_records = parse_zone_ns_data('org.ee', 10) - - DNS::Zone.create!({ - origin: 'org.ee', - ttl: 43200, - refresh: 3600, - retry: 900, - expire: 1209600, - minimum_ttl: 3600, - email: 'hostmaster.eestiinternet.ee', - master_nameserver: 'ns.tld.ee', - ns_records: ns_records, - a_records: a_records, - a4_records: a4_records - }) - - # pri.ee - ns_records, a_records, a4_records = parse_zone_ns_data('pri.ee', 2) - - DNS::Zone.create!({ - origin: 'pri.ee', - ttl: 43200, - refresh: 3600, - retry: 900, - expire: 1209600, - minimum_ttl: 3600, - email: 'hostmaster.eestiinternet.ee', - master_nameserver: 'ns.tld.ee', - ns_records: ns_records, - a_records: a_records, - a4_records: a4_records - }) - - # med.ee - ns_records, a_records, a4_records = parse_zone_ns_data('med.ee', 3) - - DNS::Zone.create!({ - origin: 'med.ee', - ttl: 43200, - refresh: 3600, - retry: 900, - expire: 1209600, - minimum_ttl: 3600, - email: 'hostmaster.eestiinternet.ee', - master_nameserver: 'ns.tld.ee', - ns_records: ns_records, - a_records: a_records, - a4_records: a4_records - }) - - # fie.ee - ns_records, a_records, a4_records = parse_zone_ns_data('fie.ee', 4) - - DNS::Zone.create!({ - origin: 'fie.ee', - ttl: 43200, - refresh: 3600, - retry: 900, - expire: 1209600, - minimum_ttl: 3600, - email: 'hostmaster.eestiinternet.ee', - master_nameserver: 'ns.tld.ee', - ns_records: ns_records, - a_records: a_records, - a4_records: a4_records - }) - - # com.ee - ns_records, a_records, a4_records = parse_zone_ns_data('com.ee', 5) - - DNS::Zone.create!({ - origin: 'com.ee', - ttl: 43200, - refresh: 3600, - retry: 900, - expire: 1209600, - minimum_ttl: 3600, - email: 'hostmaster.eestiinternet.ee', - master_nameserver: 'ns.tld.ee', - ns_records: ns_records, - a_records: a_records, - a4_records: a4_records - }) - - # gov.ee - ns_records, a_records, a4_records = parse_zone_ns_data('gov.ee', 7) - - DNS::Zone.create!({ - origin: 'gov.ee', - ttl: 43200, - refresh: 3600, - retry: 900, - expire: 1209600, - minimum_ttl: 3600, - email: 'hostmaster.eestiinternet.ee', - master_nameserver: 'ns.tld.ee', - ns_records: ns_records, - a_records: a_records, - a4_records: a4_records - }) - - # riik.ee - ns_records, a_records, a4_records = parse_zone_ns_data('riik.ee', 8) - - DNS::Zone.create!({ - origin: 'riik.ee', - ttl: 43200, - refresh: 3600, - retry: 900, - expire: 1209600, - minimum_ttl: 3600, - email: 'hostmaster.eestiinternet.ee', - master_nameserver: 'ns.tld.ee', - ns_records: ns_records, - a_records: a_records, - a4_records: a4_records - }) - - puts "-----> Imported zones in #{(Time.zone.now.to_f - start).round(2)} seconds" - end -end - -def parse_zone_ns_data(domain, zone) - ns_records = '' - a_records = '' - a4_records = '' - Legacy::ZoneNs.where(zone: zone).each do |x| - ipv4 = x.addrs.select { |addr| addr.ipv4? }.first - ipv6 = x.addrs.select { |addr| addr.ipv6? }.first - - ns_records += "#{domain}. IN NS #{x.fqdn}.\n" - a_records += "#{x.fqdn}. IN A #{ipv4}\n" if ipv4.present? - a4_records += "#{x.fqdn}. IN AAAA #{ipv6}\n" if ipv6.present? - end - [ns_records.strip, a_records.strip, a4_records.strip] -end diff --git a/lib/tasks/invoices/process_payments.rake b/lib/tasks/invoices/process_payments.rake new file mode 100644 index 000000000..340aba187 --- /dev/null +++ b/lib/tasks/invoices/process_payments.rake @@ -0,0 +1,46 @@ +namespace :invoices do + task process_payments: :environment do + registry_bank_account_iban = Setting.registry_iban + + keystore = OpenSSL::PKCS12.new(File.read(ENV['lhv_p12_keystore']), ENV['lhv_keystore_password']) + key = keystore.key + cert = keystore.certificate + + api = Lhv::ConnectApi.new + api.cert = cert + api.key = key + api.ca_file = ENV['lhv_ca_file'] + api.dev_mode = ENV['lhv_dev_mode'] == 'true' + + incoming_transactions = [] + + api.credit_debit_notification_messages.each do |message| + next unless message.bank_account_iban == registry_bank_account_iban + + message.credit_transactions.each do |credit_transaction| + incoming_transactions << credit_transaction + end + end + + if incoming_transactions.any? + bank_statement = BankStatement.new(bank_code: Setting.registry_bank_code, + iban: Setting.registry_iban) + + ActiveRecord::Base.transaction do + bank_statement.save! + + incoming_transactions.each do |incoming_transaction| + transaction_attributes = { sum: incoming_transaction.amount, + currency: incoming_transaction.currency, + paid_at: incoming_transaction.date, + reference_no: incoming_transaction.payment_reference_number, + description: incoming_transaction.payment_description } + transaction = bank_statement.bank_transactions.create!(transaction_attributes) + transaction.autobind_invoice + end + end + end + + puts "Transactions processed: #{incoming_transactions.size}" + end +end diff --git a/lib/tasks/statuses.rake b/lib/tasks/statuses.rake deleted file mode 100644 index 61adf372d..000000000 --- a/lib/tasks/statuses.rake +++ /dev/null @@ -1,625 +0,0 @@ -desc 'Schema load for all databases: registry, api_log and whois' -task statuses: [:environment] do - statuses = { - 'ok': [ - ], - 'inactive': [ - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'clientHold', - 'serverHold', - 'clientRenewProhibited', - 'serverRenewProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'serverRegistrantChangeProhibited', - 'serverAdminChangeProhibited', - 'serverTechChangeProhibited', - 'serverForceDelete', - 'deleteCandidate', - 'expired' - ], - 'clientDeleteProhibited': [ - 'serverDeleteProhibited', - 'clientHold', - 'serverHold', - 'clientRenewProhibited', - 'serverRenewProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'inactive', - 'serverManualInzone', - 'serverRegistrantChangeProhibited', - 'serverAdminChangeProhibited', - 'serverTechChangeProhibited', - 'serverForceDelete', - 'deleteCandidate', - 'expired' - ], - 'serverDeleteProhibited': [ - 'clientDeleteProhibited', - 'clientHold', - 'serverHold', - 'clientRenewProhibited', - 'serverRenewProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'inactive', - 'serverManualInzone', - 'serverRegistrantChangeProhibited', - 'serverAdminChangeProhibited', - 'serverTechChangeProhibited', - 'serverForceDelete', - 'deleteCandidate', - 'expired' - ], - 'clientHold': [ - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'serverHold', - 'clientRenewProhibited', - 'serverRenewProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'inactive', - 'serverRegistrantChangeProhibited', - 'serverAdminChangeProhibited', - 'serverTechChangeProhibited', - 'serverForceDelete', - 'deleteCandidate', - 'expired' - ], - 'serverHold': [ - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'clientHold', - 'clientRenewProhibited', - 'serverRenewProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'inactive', - 'serverRegistrantChangeProhibited', - 'serverAdminChangeProhibited', - 'serverTechChangeProhibited', - 'serverForceDelete', - 'deleteCandidate', - 'expired' - ], - 'clientRenewProhibited': [ - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'clientHold', - 'serverHold', - 'serverRenewProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'inactive', - 'pendingCreate', - 'pendingDelete', - 'pendingDeleteConfirmation', - 'pendingTransfer', - 'pendingUpdate', - 'serverManualInzone', - 'serverRegistrantChangeProhibited', - 'serverAdminChangeProhibited', - 'serverTechChangeProhibited', - 'serverForceDelete', - 'deleteCandidate', - 'expired' - ], - 'serverRenewProhibited': [ - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'clientHold', - 'serverHold', - 'clientRenewProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'inactive', - 'pendingCreate', - 'pendingDelete', - 'pendingDeleteConfirmation', - 'pendingTransfer', - 'pendingUpdate', - 'serverManualInzone', - 'serverRegistrantChangeProhibited', - 'serverAdminChangeProhibited', - 'serverTechChangeProhibited', - 'serverForceDelete', - 'deleteCandidate', - 'expired' - ], - 'clientTransferProhibited': [ - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'clientHold', - 'serverHold', - 'clientRenewProhibited', - 'serverRenewProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'inactive', - 'pendingCreate', - 'pendingDelete', - 'pendingDeleteConfirmation', - 'pendingRenew', - 'pendingUpdate', - 'serverManualInzone', - 'serverRegistrantChangeProhibited', - 'serverAdminChangeProhibited', - 'serverTechChangeProhibited', - 'serverForceDelete', - 'deleteCandidate', - 'expired' - ], - 'serverTransferProhibited': [ - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'clientHold', - 'serverHold', - 'clientRenewProhibited', - 'serverRenewProhibited', - 'clientTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'inactive', - 'pendingCreate', - 'pendingDelete', - 'pendingDeleteConfirmation', - 'pendingRenew', - 'pendingUpdate', - 'serverManualInzone', - 'serverRegistrantChangeProhibited', - 'serverAdminChangeProhibited', - 'serverTechChangeProhibited', - 'serverForceDelete', - 'deleteCandidate', - 'expired' - ], - 'clientUpdateProhibited': [ - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'clientHold', - 'serverHold', - 'clientRenewProhibited', - 'serverRenewProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'serverUpdateProhibited', - 'inactive', - 'pendingCreate', - 'pendingDelete', - 'pendingDeleteConfirmation', - 'pendingRenew', - 'pendingTransfer', - 'serverManualInzone', - 'serverRegistrantChangeProhibited', - 'serverAdminChangeProhibited', - 'serverTechChangeProhibited', - 'serverForceDelete', - 'deleteCandidate', - 'expired' - ], - 'serverUpdateProhibited': [ - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'clientHold', - 'serverHold', - 'clientRenewProhibited', - 'serverRenewProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'inactive', - 'pendingCreate', - 'pendingDelete', - 'pendingDeleteConfirmation', - 'pendingRenew', - 'pendingTransfer', - 'serverManualInzone', - 'serverRegistrantChangeProhibited', - 'serverAdminChangeProhibited', - 'serverTechChangeProhibited', - 'serverForceDelete', - 'deleteCandidate', - 'expired' - ], - 'pendingCreate': [ - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'clientHold', - 'serverHold', - 'clientRenewProhibited', - 'serverRenewProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'inactive', - 'serverManualInzone', - 'serverRegistrantChangeProhibited', - 'serverAdminChangeProhibited', - 'serverTechChangeProhibited', - 'serverForceDelete', - 'deleteCandidate', - 'expired' - ], - 'pendingDelete': [ - 'clientHold', - 'serverHold', - 'clientRenewProhibited', - 'serverRenewProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'inactive', - 'pendingDeleteConfirmation', - 'serverManualInzone', - 'serverRegistrantChangeProhibited', - 'serverAdminChangeProhibited', - 'serverTechChangeProhibited', - 'serverForceDelete', - 'deleteCandidate', - 'expired' - ], - 'pendingRenew': [ - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'clientHold', - 'serverHold', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'inactive', - 'serverManualInzone', - 'serverRegistrantChangeProhibited', - 'serverAdminChangeProhibited', - 'serverTechChangeProhibited', - 'serverForceDelete', - 'deleteCandidate', - 'expired' - - ], - 'pendingTransfer': [ - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'clientHold', - 'serverHold', - 'clientRenewProhibited', - 'serverRenewProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'inactive', - 'serverManualInzone', - 'serverRegistrantChangeProhibited', - 'serverAdminChangeProhibited', - 'serverTechChangeProhibited', - 'serverForceDelete', - 'deleteCandidate', - 'expired' - ], - 'pendingUpdate': [ - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'clientHold', - 'serverHold', - 'clientRenewProhibited', - 'serverRenewProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'inactive', - 'serverManualInzone', - 'serverRegistrantChangeProhibited', - 'serverAdminChangeProhibited', - 'serverTechChangeProhibited', - 'serverForceDelete', - 'deleteCandidate', - 'expired' - ], - 'serverManualInzone': [ - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'clientHold', - 'serverHold', - 'clientRenewProhibited', - 'serverRenewProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'pendingCreate', - 'pendingDelete', - 'pendingDeleteConfirmation', - 'pendingRenew', - 'pendingTransfer', - 'pendingUpdate', - 'serverRegistrantChangeProhibited', - 'serverAdminChangeProhibited', - 'serverTechChangeProhibited', - 'serverForceDelete', - 'deleteCandidate', - 'expired' - ], - 'serverRegistrantChangeProhibited': [ - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'clientHold', - 'serverHold', - 'clientRenewProhibited', - 'serverRenewProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'inactive', - 'pendingCreate', - 'pendingDelete', - 'pendingDeleteConfirmation', - 'pendingRenew', - 'pendingTransfer', - 'pendingUpdate', - 'serverManualInzone', - 'serverAdminChangeProhibited', - 'serverTechChangeProhibited', - 'serverForceDelete', - 'deleteCandidate', - 'expired' - ], - 'serverAdminChangeProhibited': [ - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'clientHold', - 'serverHold', - 'clientRenewProhibited', - 'serverRenewProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'inactive', - 'pendingCreate', - 'pendingDelete', - 'pendingDeleteConfirmation', - 'pendingRenew', - 'pendingTransfer', - 'pendingUpdate', - 'serverManualInzone', - 'serverRegistrantChangeProhibited', - 'serverTechChangeProhibited', - 'serverForceDelete', - 'deleteCandidate', - 'expired' - ], - 'serverTechChangeProhibited': [ - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'clientHold', - 'serverHold', - 'clientRenewProhibited', - 'serverRenewProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'inactive', - 'pendingCreate', - 'pendingDelete', - 'pendingDeleteConfirmation', - 'pendingRenew', - 'pendingTransfer', - 'pendingUpdate', - 'serverManualInzone', - 'serverRegistrantChangeProhibited', - 'serverAdminChangeProhibited', - 'serverForceDelete', - 'deleteCandidate', - 'expired' - ], - 'serverForceDelete': [ - 'clientHold', - 'serverHold', - 'inactive', - 'serverManualInzone', - 'serverRegistrantChangeProhibited', - 'serverAdminChangeProhibited', - 'serverTechChangeProhibited', - 'deleteCandidate', - 'expired' - ], - 'deleteCandidate': [ - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'clientHold', - 'serverHold', - 'clientRenewProhibited', - 'serverRenewProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'inactive', - 'pendingCreate', - 'pendingDelete', - 'pendingDeleteConfirmation', - 'pendingRenew', - 'pendingTransfer', - 'pendingUpdate', - 'serverManualInzone', - 'serverRegistrantChangeProhibited', - 'serverAdminChangeProhibited', - 'serverTechChangeProhibited', - 'serverForceDelete', - 'deleteCandidate', - 'expired' - ], - 'expired': [ - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'clientHold', - 'serverHold', - 'clientRenewProhibited', - 'serverRenewProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'inactive', - 'pendingCreate', - 'pendingDelete', - 'pendingDeleteConfirmation', - 'pendingRenew', - 'pendingTransfer', - 'pendingUpdate', - 'serverManualInzone', - 'serverRegistrantChangeProhibited', - 'serverAdminChangeProhibited', - 'serverTechChangeProhibited', - 'serverForceDelete', - 'deleteCandidate' - ] - } - - puts "\nDomain status can be with other statuses map\n" - puts "---------------------------------------------" - statuses.each do |s, _v| - puts "\n#{s} =>" - statuses[s].map { |u| puts " #{u}" } - puts - end - - contact_statuses = { - 'ok': [ - 'linked' - ], - 'linked': [ - 'ok' - ], - 'clientDeleteProhibited': [ - 'linked', - 'serverDeleteProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'pendingCreate', - 'pendingTransfer', - 'pendingUpdate' - ], - 'serverDeleteProhibited': [ - 'linked', - 'clientDeleteProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'pendingCreate', - 'pendingTransfer', - 'pendingUpdate' - ], - 'clientTransferProhibited': [ - 'linked', - 'serverDeleteProhibited', - 'clientDeleteProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'pendingCreate', - 'pendingDelete', - 'pendingUpdate' - ], - 'serverTransferProhibited': [ - 'linked', - 'serverDeleteProhibited', - 'clientDeleteProhibited', - 'clientTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited', - 'pendingCreate', - 'pendingDelete', - 'pendingUpdate' - ], - 'clientUpdateProhibited': [ - 'linked', - 'serverDeleteProhibited', - 'clientDeleteProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'serverUpdateProhibited', - 'pendingCreate', - 'pendingDelete', - 'pendingTransfer' - ], - 'serverUpdateProhibited': [ - 'linked', - 'serverDeleteProhibited', - 'clientDeleteProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'pendingCreate', - 'pendingDelete', - 'pendingTransfer' - ], - 'pendingCreate': [ - 'linked', - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited' - ], - 'pendingDelete': [ - 'linked', - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited' - ], - 'pendingTransfer': [ - 'linked', - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited' - ], - 'pendingUpdate': [ - 'linked', - 'clientDeleteProhibited', - 'serverDeleteProhibited', - 'clientTransferProhibited', - 'serverTransferProhibited', - 'clientUpdateProhibited', - 'serverUpdateProhibited' - ] - } - - puts "\n\nContact status can be with other statuses map\n" - puts "---------------------------------------------" - contact_statuses.each do |s, _v| - puts "\n#{s} =>" - contact_statuses[s].map { |u| puts " #{u}" } - puts - end -end diff --git a/lib/tasks/verify_email.rake b/lib/tasks/verify_email.rake new file mode 100644 index 000000000..d49bb38b9 --- /dev/null +++ b/lib/tasks/verify_email.rake @@ -0,0 +1,23 @@ +namespace :verify_email do + desc 'Stars verifying email jobs for all the domain' + task all_domains: :environment do + verifications_by_domain = EmailAddressVerification.not_verified_recently.group_by(&:domain) + verifications_by_domain.each do |_domain, verifications| + ver = verifications.sample # Verify random email to not to clog the SMTP servers + VerifyEmailsJob.enqueue(ver.id) + next + end + end + + # Need to be run like 'bundle exec rake verify_email:domain['gmail.com']' + # In zsh syntax will be 'bundle exec rake verify_email:domain\['gmail.com'\]' + # Default 'bundle exec rake verify_email:domain' wil use 'internet.ee' domain + desc 'Stars verifying email jobs for domain stated in argument' + task :domain, [:domain_name] => [:environment] do |_task, args| + args.with_defaults(domain_name: 'internet.ee') + + verifications_by_domain = EmailAddressVerification.not_verified_recently + .by_domain(args[:domain_name]) + verifications_by_domain.map { |ver| VerifyEmailsJob.enqueue(ver.id) } + end +end diff --git a/lib/tasks/whois.rake b/lib/tasks/whois.rake index c38b2c5ba..52be7e17f 100644 --- a/lib/tasks/whois.rake +++ b/lib/tasks/whois.rake @@ -35,6 +35,11 @@ namespace :whois do ReservedDomain.find_in_batches.each do |group| UpdateWhoisRecordJob.enqueue group.map(&:name), 'reserved' end + + print "\n-----> Update disputed domains whois_records" + Dispute.active.find_in_batches.each do |group| + UpdateWhoisRecordJob.enqueue group.map(&:domain_name), 'disputed' + end end puts "\n-----> all done in #{(Time.zone.now.to_f - start).round(2)} seconds" end diff --git a/spec/api/repp/contact_v1_spec.rb b/spec/api/repp/contact_v1_spec.rb deleted file mode 100644 index 77ce38d2e..000000000 --- a/spec/api/repp/contact_v1_spec.rb +++ /dev/null @@ -1,50 +0,0 @@ -require 'rails_helper' - -RSpec.describe Repp::ContactV1, db: true do - let(:user) { create(:api_user, registrar: registrar) } - let(:registrar) { create(:registrar) } - - describe '/contacts' do - let(:returned_attributes) { HashWithIndifferentAccess.new(JSON.parse(response.body)['contacts'].first).keys } - subject(:address_included) { Contact.address_attribute_names.any? { |attr| returned_attributes.include?(attr.to_s) } } - - before do - Grape::Endpoint.before_each do |endpoint| - allow(endpoint).to receive(:current_user).and_return(user) - end - - registrar.contacts << create(:contact) - end - - it 'responds with success' do - get '/repp/v1/contacts', { limit: 1, details: true }, { 'HTTP_AUTHORIZATION' => http_auth_key } - expect(response).to have_http_status(:success) - end - - context 'when address processing is enabled' do - before do - expect(Contact).to receive(:address_processing?).and_return(true) - get '/repp/v1/contacts', { limit: 1, details: true }, { 'HTTP_AUTHORIZATION' => http_auth_key } - end - - it 'returns contact address' do - expect(address_included).to be_truthy - end - end - - context 'when address processing is disabled' do - before do - expect(Contact).to receive(:address_processing?).and_return(false) - get '/repp/v1/contacts', { limit: 1, details: true }, { 'HTTP_AUTHORIZATION' => http_auth_key } - end - - it 'does not return contact address' do - expect(address_included).to be_falsy - end - end - end - - def http_auth_key - ActionController::HttpAuthentication::Basic.encode_credentials(user.username, user.plain_text_password) - end -end diff --git a/spec/factories/account.rb b/spec/factories/account.rb deleted file mode 100644 index 4407b1f86..000000000 --- a/spec/factories/account.rb +++ /dev/null @@ -1,8 +0,0 @@ -FactoryBot.define do - factory :account do - account_type Account::CASH - balance 1 - currency 'EUR' - registrar - end -end diff --git a/spec/factories/account_activity.rb b/spec/factories/account_activity.rb deleted file mode 100644 index b5dd348f2..000000000 --- a/spec/factories/account_activity.rb +++ /dev/null @@ -1,6 +0,0 @@ -FactoryBot.define do - factory :account_activity do - sum 1.0 - account - end -end diff --git a/spec/factories/admin_domain_contact.rb b/spec/factories/admin_domain_contact.rb deleted file mode 100644 index bdfb193e3..000000000 --- a/spec/factories/admin_domain_contact.rb +++ /dev/null @@ -1,5 +0,0 @@ -FactoryBot.define do - factory :admin_domain_contact, parent: :domain_contact, class: AdminDomainContact do - - end -end diff --git a/spec/factories/admin_user.rb b/spec/factories/admin_user.rb deleted file mode 100644 index 8f948062d..000000000 --- a/spec/factories/admin_user.rb +++ /dev/null @@ -1,10 +0,0 @@ -FactoryBot.define do - factory :admin_user do - username 'test' - sequence(:email) { |n| "test#{n}@test.com" } - password 'a' * AdminUser.min_password_length - password_confirmation { password } - country_code 'de' - roles ['admin'] - end -end diff --git a/spec/factories/api_user.rb b/spec/factories/api_user.rb deleted file mode 100644 index 01ba0f8da..000000000 --- a/spec/factories/api_user.rb +++ /dev/null @@ -1,23 +0,0 @@ -FactoryBot.define do - factory :api_user do - sequence(:username) { |n| "test#{n}" } - plain_text_password 'a' * ApiUser.min_password_length - roles ['super'] - registrar - - factory :api_user_epp do - roles %w(epp static_registrant) - end - - factory :api_user_with_unlimited_balance do - transient do - registrar false - end - - after :build do |api_user, evaluator| - registrar = (evaluator.registrar || create(:registrar_with_unlimited_balance)) - api_user.registrar = registrar - end - end - end -end diff --git a/spec/factories/bank_transaction.rb b/spec/factories/bank_transaction.rb deleted file mode 100644 index ebe471984..000000000 --- a/spec/factories/bank_transaction.rb +++ /dev/null @@ -1,8 +0,0 @@ -FactoryBot.define do - factory :bank_transaction do - currency { 'EUR' } - sum { 100.0 } - description { 'Invoice no. 1' } - reference_no { 'RF2405752128' } - end -end diff --git a/spec/factories/billing/price.rb b/spec/factories/billing/price.rb deleted file mode 100644 index 4d44cf6a1..000000000 --- a/spec/factories/billing/price.rb +++ /dev/null @@ -1,18 +0,0 @@ -FactoryBot.define do - factory :price, class: Billing::Price do - price Money.from_amount(1) - valid_from Time.zone.parse('05.07.2010') - valid_to Time.zone.parse('05.07.2010') - duration '1 year' - operation_category Billing::Price.operation_categories.first - zone - - factory :effective_price do - expire_time { Time.zone.now + 1.day } - end - - factory :expired_price do - expire_time { Time.zone.now - 1.day } - end - end -end diff --git a/spec/factories/contact.rb b/spec/factories/contact.rb deleted file mode 100644 index 7e7a9a6a2..000000000 --- a/spec/factories/contact.rb +++ /dev/null @@ -1,39 +0,0 @@ -FactoryBot.define do - factory :contact do - name 'test' - sequence(:code) { |n| "test#{n}" } - phone '+123.456789' - email 'test@test.com' - street 'test' - city 'test' - zip 12345 - country_code 'EE' - ident '37605030299' - ident_type 'priv' - ident_country_code 'EE' - registrar - - factory :contact_private_entity do - ident_type 'priv' - end - - factory :contact_legal_entity do - ident_type 'org' - ident '12345678' # valid reg no for .ee - end - - factory :contact_with_address do - street 'test' - city 'test' - zip 12345 - country_code 'EE' - end - - factory :contact_without_address do - street nil - city nil - zip nil - country_code nil - end - end -end diff --git a/spec/factories/dns/zone.rb b/spec/factories/dns/zone.rb deleted file mode 100644 index e88a3f2fe..000000000 --- a/spec/factories/dns/zone.rb +++ /dev/null @@ -1,12 +0,0 @@ -FactoryBot.define do - factory :zone, class: DNS::Zone do - sequence(:origin) { |n| "test#{n}" } - ttl 1 - refresh 1 - add_attribute :retry, 1 - expire 1 - minimum_ttl 1 - email 'test.test' - master_nameserver 'test.test' - end -end diff --git a/spec/factories/dnskey.rb b/spec/factories/dnskey.rb deleted file mode 100644 index 4dbf0a788..000000000 --- a/spec/factories/dnskey.rb +++ /dev/null @@ -1,15 +0,0 @@ -FactoryBot.define do - factory :dnskey do - alg Dnskey::ALGORITHMS.first - flags Dnskey::FLAGS.first - protocol Dnskey::PROTOCOLS.first - ds_digest_type 2 - public_key 'AwEAAaOf5+lz3ftsL+0CCvfJbhUF/NVsNh8BKo61oYs5fXVbuWDiH872 '\ - 'LC8uKDO92TJy7Q4TF9XMAKMMlf1GMAxlRspD749SOCTN00sqfWx1OMTu '\ - 'a28L1PerwHq7665oDJDKqR71btcGqyLKhe2QDvCdA0mENimF1NudX1BJ '\ - 'DDFi6oOZ0xE/0CuveB64I3ree7nCrwLwNs56kXC4LYoX3XdkOMKiJLL/ '\ - 'MAhcxXa60CdZLoRtTEW3z8/oBq4hEAYMCNclpbd6y/exScwBxFTdUfFk '\ - 'KsdNcmvai1lyk9vna0WQrtpYpHKMXvY9LFHaJxCOLR4umfeQ42RuTd82 lqfU6ClMeXs=' - domain - end -end diff --git a/spec/factories/domain.rb b/spec/factories/domain.rb deleted file mode 100644 index 39ad2240d..000000000 --- a/spec/factories/domain.rb +++ /dev/null @@ -1,15 +0,0 @@ -FactoryBot.define do - factory :domain do - sequence(:name) { |n| "test#{n}.com" } - period 1 - period_unit 'y' # Year - valid_to Time.zone.parse('2010-07-05') - registrar - registrant - - after :build do |domain| - domain.admin_domain_contacts << FactoryBot.build(:admin_domain_contact) - domain.tech_domain_contacts << FactoryBot.build(:tech_domain_contact) - end - end -end diff --git a/spec/factories/domain_contact.rb b/spec/factories/domain_contact.rb deleted file mode 100644 index caf964ed3..000000000 --- a/spec/factories/domain_contact.rb +++ /dev/null @@ -1,5 +0,0 @@ -FactoryBot.define do - factory :domain_contact do - contact - end -end diff --git a/spec/factories/epp_session.rb b/spec/factories/epp_session.rb deleted file mode 100644 index 296368a92..000000000 --- a/spec/factories/epp_session.rb +++ /dev/null @@ -1,6 +0,0 @@ -FactoryBot.define do - factory :epp_session do - sequence(:session_id) { |n| "test#{n}" } - association :user, factory: :api_user - end -end diff --git a/spec/factories/keyrelay.rb b/spec/factories/keyrelay.rb deleted file mode 100644 index 4587af999..000000000 --- a/spec/factories/keyrelay.rb +++ /dev/null @@ -1,12 +0,0 @@ -FactoryBot.define do - factory :keyrelay do - pa_date { Time.zone.now } - expiry_relative 'P1W' - key_data_public_key 'abc' - key_data_flags 0 - key_data_protocol 3 - key_data_alg 3 - auth_info_pw 'abc' - domain - end -end diff --git a/spec/factories/nameserver.rb b/spec/factories/nameserver.rb deleted file mode 100644 index ee0a7f987..000000000 --- a/spec/factories/nameserver.rb +++ /dev/null @@ -1,7 +0,0 @@ -FactoryBot.define do - factory :nameserver do - sequence(:hostname) { |n| "ns.test#{n}.ee" } - ipv4 '192.168.1.1' - domain - end -end diff --git a/spec/factories/registrant.rb b/spec/factories/registrant.rb deleted file mode 100644 index f21fbe7c4..000000000 --- a/spec/factories/registrant.rb +++ /dev/null @@ -1,10 +0,0 @@ -FactoryBot.define do - factory :registrant, parent: :contact, class: Registrant do - name 'test' - - factory :registrant_private_entity, class: Registrant, parent: :contact_private_entity - factory :registrant_legal_entity, class: Registrant, parent: :contact_legal_entity - factory :registrant_with_address, class: Registrant, parent: :contact_with_address - factory :registrant_without_address, class: Registrant, parent: :contact_without_address - end -end diff --git a/spec/factories/registrant_user.rb b/spec/factories/registrant_user.rb deleted file mode 100644 index 29d0a2479..000000000 --- a/spec/factories/registrant_user.rb +++ /dev/null @@ -1,5 +0,0 @@ -FactoryBot.define do - factory :registrant_user do - - end -end diff --git a/spec/factories/registrant_verification.rb b/spec/factories/registrant_verification.rb deleted file mode 100644 index 5ecc81fa5..000000000 --- a/spec/factories/registrant_verification.rb +++ /dev/null @@ -1,9 +0,0 @@ -FactoryBot.define do - factory :registrant_verification do - sequence(:domain_name) { |i| "domain#{i}.ee" } - domain - verification_token '123' - action 'confirmed' - action_type 'registrant_change' - end -end diff --git a/spec/factories/registrar.rb b/spec/factories/registrar.rb deleted file mode 100644 index 2bc945900..000000000 --- a/spec/factories/registrar.rb +++ /dev/null @@ -1,26 +0,0 @@ -FactoryBot.define do - factory :registrar do - sequence(:name) { |n| "test#{n}" } - sequence(:code) { |n| "test#{n}" } - sequence(:reg_no) { |n| "test#{n}" } - email 'test@test.com' - address_street 'test' - address_city 'test' - address_country_code 'US' - accounting_customer_code 'test' - language 'en' - sequence(:reference_no) { |n| "1234#{n}" } - - factory :registrar_with_unlimited_balance do - after :create do |registrar| - create(:account, registrar: registrar, balance: 1_000_000) - end - end - - factory :registrar_with_zero_balance do - after :create do |registrar| - create(:account, registrar: registrar, balance: 0) - end - end - end -end diff --git a/spec/factories/reserved_domain.rb b/spec/factories/reserved_domain.rb deleted file mode 100644 index 54d3c61df..000000000 --- a/spec/factories/reserved_domain.rb +++ /dev/null @@ -1,5 +0,0 @@ -FactoryBot.define do - factory :reserved_domain do - sequence(:name) { |i| "domain#{i}.ee" } - end -end diff --git a/spec/factories/tech_domain_contact.rb b/spec/factories/tech_domain_contact.rb deleted file mode 100644 index b3b3f0564..000000000 --- a/spec/factories/tech_domain_contact.rb +++ /dev/null @@ -1,5 +0,0 @@ -FactoryBot.define do - factory :tech_domain_contact, parent: :domain_contact, class: TechDomainContact do - - end -end diff --git a/spec/factories/white_ip.rb b/spec/factories/white_ip.rb deleted file mode 100644 index f2b46711c..000000000 --- a/spec/factories/white_ip.rb +++ /dev/null @@ -1,5 +0,0 @@ -FactoryBot.define do - factory :white_ip do - ipv4 '127.0.0.1' - end -end diff --git a/spec/factory_lint_spec.rb b/spec/factory_lint_spec.rb deleted file mode 100644 index 8d6386f2f..000000000 --- a/spec/factory_lint_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -require_relative 'rails_helper' - -RSpec.describe 'FactoryBot', db: true do - before :example do - allow(Contact).to receive(:address_processing?).and_return(false) - end - - it 'lints factories' do - factories_to_lint = FactoryBot.factories.reject do |factory| - %i(reserved_domain).include?(factory.name) || factory.name.to_s =~ /^domain/ # Ignore the ones with domain_name validator - end - - FactoryBot.lint factories_to_lint - end -end diff --git a/spec/features/admin/billing/prices/edit_spec.rb b/spec/features/admin/billing/prices/edit_spec.rb deleted file mode 100644 index 8ef87b9a0..000000000 --- a/spec/features/admin/billing/prices/edit_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -require 'rails_helper' - -RSpec.feature 'Editing price in admin area', settings: false do - given!(:price) { create(:effective_price) } - - background do - sign_in_to_admin_area - end - - scenario 'updates price' do - visit admin_prices_path - open_form - submit_form - - expect(page).to have_text(t('admin.billing.prices.update.updated')) - end - - def open_form - find('.edit-price-btn').click - end - - def submit_form - click_link_or_button t('admin.billing.prices.form.update_btn') - end -end diff --git a/spec/features/admin/billing/prices/expire_spec.rb b/spec/features/admin/billing/prices/expire_spec.rb deleted file mode 100644 index 9a835f09c..000000000 --- a/spec/features/admin/billing/prices/expire_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -require 'rails_helper' - -RSpec.feature 'Expiring price in admin area', settings: false do - given!(:price) { create(:effective_price) } - - background do - sign_in_to_admin_area - end - - scenario 'expires price' do - visit admin_prices_path - open_edit_form - expire - - expect(page).to have_text(t('admin.billing.prices.expire.expired')) - end - - def open_edit_form - find('.edit-price-btn').click - end - - def expire - click_link_or_button t('admin.billing.prices.edit.expire_btn') - end -end diff --git a/spec/features/admin/billing/prices/list_spec.rb b/spec/features/admin/billing/prices/list_spec.rb deleted file mode 100644 index 95ebcb975..000000000 --- a/spec/features/admin/billing/prices/list_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -require 'rails_helper' - -RSpec.feature 'Viewing prices in admin area', settings: false do - given!(:effective_price) { create(:effective_price) } - given!(:expired_price) { create(:expired_price) } - - background do - sign_in_to_admin_area - end - - describe 'search' do - context 'when status is not selected' do - scenario 'shows effective prices' do - visit admin_prices_path - expect(page).to have_css('.price', count: 1) - end - end - - context 'when status is given' do - scenario 'filters by given status' do - visit admin_prices_path - select Admin::Billing::PricesController.default_status.capitalize, from: 'search_status' - submit_search_form - - expect(page).to have_css('.price', count: 1) - end - end - - def submit_search_form - find('.price-search-form-search-btn').click - end - end -end diff --git a/spec/features/admin/billing/prices/new_spec.rb b/spec/features/admin/billing/prices/new_spec.rb deleted file mode 100644 index 9d11938bb..000000000 --- a/spec/features/admin/billing/prices/new_spec.rb +++ /dev/null @@ -1,37 +0,0 @@ -require 'rails_helper' - -RSpec.feature 'New price in admin area', settings: false do - given!(:zone) { create(:zone, origin: 'test') } - - background do - sign_in_to_admin_area - end - - scenario 'it creates new price' do - open_list - open_form - fill_form - submit_form - - expect(page).to have_text(t('admin.billing.prices.create.created')) - end - - def open_list - click_link_or_button t('admin.base.menu.prices') - end - - def open_form - click_link_or_button t('admin.billing.prices.index.new_btn') - end - - def fill_form - select 'test', from: 'price_zone_id' - select Billing::Price.operation_categories.first, from: 'price_operation_category' - select '3 months', from: 'price_duration' - fill_in 'price_price', with: '1' - end - - def submit_form - click_link_or_button t('admin.billing.prices.form.create_btn') - end -end diff --git a/spec/features/admin/dns/zones/edit_spec.rb b/spec/features/admin/dns/zones/edit_spec.rb deleted file mode 100644 index 8b61683ce..000000000 --- a/spec/features/admin/dns/zones/edit_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ -require 'rails_helper' - -RSpec.feature 'Editing zone in admin area', settings: false do - given!(:zone) { create(:zone) } - - background do - sign_in_to_admin_area - end - - scenario 'updates zone' do - visit admin_zones_url - open_form - submit_form - - expect(page).to have_text(t('admin.dns.zones.update.updated')) - end - - def open_list - click_link_or_button t('admin.base.menu.zones') - end - - def open_form - click_link_or_button 'admin-edit-zone-btn' - end - - def submit_form - click_link_or_button t('admin.dns.zones.form.update_btn') - end -end diff --git a/spec/features/admin/dns/zones/new_spec.rb b/spec/features/admin/dns/zones/new_spec.rb deleted file mode 100644 index 78fd05195..000000000 --- a/spec/features/admin/dns/zones/new_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -require 'rails_helper' - -RSpec.feature 'New zone in admin area', settings: false do - background do - sign_in_to_admin_area - end - - scenario 'it creates new zone' do - open_list - open_form - fill_form - submit_form - - expect(page).to have_text(t('admin.dns.zones.create.created')) - end - - def open_list - click_link_or_button t('admin.base.menu.zones') - end - - def open_form - click_link_or_button t('admin.dns.zones.index.new_btn') - end - - def fill_form - fill_in 'zone_origin', with: 'test' - fill_in 'zone_ttl', with: '1' - fill_in 'zone_refresh', with: '1' - fill_in 'zone_retry', with: '1' - fill_in 'zone_expire', with: '1' - fill_in 'zone_minimum_ttl', with: '1' - fill_in 'zone_email', with: 'test@test.com' - fill_in 'zone_master_nameserver', with: 'test.test' - end - - def submit_form - click_link_or_button t('admin.dns.zones.form.create_btn') - end -end diff --git a/spec/features/admin/settings/create_spec.rb b/spec/features/admin/settings/create_spec.rb deleted file mode 100644 index d30e93e8e..000000000 --- a/spec/features/admin/settings/create_spec.rb +++ /dev/null @@ -1,13 +0,0 @@ -require 'rails_helper' - -RSpec.feature 'Admin settings' do - background do - sign_in_to_admin_area - end - - it 'saves settings' do - visit admin_settings_path - click_link_or_button 'Save' - expect(page).to have_text(t('admin.settings.create.saved')) - end -end diff --git a/spec/features/registrar/contacts/delete_spec.rb b/spec/features/registrar/contacts/delete_spec.rb deleted file mode 100644 index d0169ad54..000000000 --- a/spec/features/registrar/contacts/delete_spec.rb +++ /dev/null @@ -1,50 +0,0 @@ -require 'rails_helper' - -class FakeDeppContact - include ActiveModel::Model - - def id - 'test' - end - - def name - 'test' - end - - def persisted? - true - end - - def password - 'test' - end - - def delete - true - end -end - -RSpec.feature 'Contact deletion in registrar area' do - given!(:registrar) { create(:registrar) } - given!(:contact) { create(:contact, registrar: registrar) } - - background do - allow(Depp::Contact).to receive(:find_by_id).and_return(FakeDeppContact.new) - allow(Depp::Contact).to receive(:new).and_return(FakeDeppContact.new) - sign_in_to_registrar_area(user: create(:api_user_with_unlimited_balance, registrar: registrar)) - end - - it 'deletes contact' do - visit registrar_contacts_url - click_link_or_button 'Delete' - confirm - - expect(page).to have_text('Destroyed') - end - - private - - def confirm - click_link_or_button 'Delete' - end -end diff --git a/spec/features/registrar/contacts/list_spec.rb b/spec/features/registrar/contacts/list_spec.rb deleted file mode 100644 index 96f1f2c98..000000000 --- a/spec/features/registrar/contacts/list_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'rails_helper' - -RSpec.feature 'Contact list', settings: false do - given!(:registrar) { create(:registrar) } - given!(:contact) { create(:contact, registrar: registrar) } - - background do - sign_in_to_registrar_area(user: create(:api_user_with_unlimited_balance, registrar: registrar)) - end - - it 'is visible' do - visit registrar_contacts_path - expect(page).to have_css('.contacts') - end -end diff --git a/spec/features/registrar/domains/new_spec.rb b/spec/features/registrar/domains/new_spec.rb deleted file mode 100644 index 4dd1d85d5..000000000 --- a/spec/features/registrar/domains/new_spec.rb +++ /dev/null @@ -1,14 +0,0 @@ -require 'rails_helper' - -RSpec.feature 'New domain in registrar area', settings: false do - background do - sign_in_to_registrar_area - end - - it 'has default period' do - visit registrar_domains_path - click_link_or_button t('new') - - expect(page).to have_field('domain_period', with: Depp::Domain.default_period) - end -end diff --git a/spec/features/registrar/domains/renew_spec.rb b/spec/features/registrar/domains/renew_spec.rb deleted file mode 100644 index 1d6ab0a7e..000000000 --- a/spec/features/registrar/domains/renew_spec.rb +++ /dev/null @@ -1,18 +0,0 @@ -require 'rails_helper' - -RSpec.feature 'Renew domain in registrar area' do - given!(:registrar) { create(:registrar) } - given!(:user) { create(:api_user, registrar: registrar) } - given!(:domain) { create(:domain, registrar: registrar) } - - background do - sign_in_to_registrar_area(user: user) - end - - it 'has default period' do - visit registrar_domains_path - click_link_or_button t('renew') - - expect(page).to have_field('period', with: Depp::Domain.default_period) - end -end diff --git a/spec/features/registrar/ip_restriction_spec.rb b/spec/features/registrar/ip_restriction_spec.rb deleted file mode 100644 index 264c45283..000000000 --- a/spec/features/registrar/ip_restriction_spec.rb +++ /dev/null @@ -1,17 +0,0 @@ -require 'rails_helper' - -RSpec.feature 'Registrar area IP restriction', settings: false do - before do - @original_registrar_ip_whitelist_enabled = Setting.registrar_ip_whitelist_enabled - end - - after do - Setting.registrar_ip_whitelist_enabled = @original_registrar_ip_whitelist_enabled - end - - scenario 'notifies the user if his IP is not allowed' do - Setting.registrar_ip_whitelist_enabled = true - visit registrar_root_path - expect(page).to have_text('Access denied from IP 127.0.0.1') - end -end diff --git a/spec/features/registrar/linked_users_spec.rb b/spec/features/registrar/linked_users_spec.rb deleted file mode 100644 index aa1e3785b..000000000 --- a/spec/features/registrar/linked_users_spec.rb +++ /dev/null @@ -1,17 +0,0 @@ -require 'rails_helper' - -RSpec.feature 'Registrar area linked users', settings: false do - given!(:current_user) { create(:api_user_with_unlimited_balance, id: 1, identity_code: 'test') } - given!(:linked_user) { create(:api_user_with_unlimited_balance, id: 2, identity_code: 'test', - username: 'new-user-name') } - - background do - sign_in_to_registrar_area(user: current_user) - end - - scenario 'switches current user to a linked one' do - visit registrar_account_path - click_link_or_button 'switch-current-user-2-btn' - expect(page).to have_text('You are now signed in as a user "new-user-name"') - end -end diff --git a/spec/jobs/domain_expire_email_job_spec.rb b/spec/jobs/domain_expire_email_job_spec.rb deleted file mode 100644 index a25999b77..000000000 --- a/spec/jobs/domain_expire_email_job_spec.rb +++ /dev/null @@ -1,43 +0,0 @@ -require 'rails_helper' - -RSpec.describe DomainExpireEmailJob do - describe '#run' do - let(:domain) { instance_double(Domain) } - - before :example do - expect(Domain).to receive(:find).and_return(domain) - end - - after :example do - domain_id = 1 - described_class.enqueue(domain_id) - end - - context 'when domain is expired' do - let(:message) { instance_double(ActionMailer::MessageDelivery) } - - before :example do - allow(domain).to receive_messages( - registrar: 'registrar', - registered?: false, - primary_contact_emails: %w(test@test.com test@test.com)) - end - - it 'sends email' do - expect(DomainExpireMailer).to receive(:expired).with(domain: domain, registrar: 'registrar') - .and_return(message) - expect(message).to receive(:deliver_now) - end - end - - context 'when domain is registered' do - before :example do - allow(domain).to receive(:registered?).and_return(true) - end - - it 'does not send email' do - expect(DomainExpireMailer).to_not receive(:expired) - end - end - end -end diff --git a/spec/jobs/registrant_change_expired_email_job_spec.rb b/spec/jobs/registrant_change_expired_email_job_spec.rb deleted file mode 100644 index 1486417ea..000000000 --- a/spec/jobs/registrant_change_expired_email_job_spec.rb +++ /dev/null @@ -1,40 +0,0 @@ -require 'rails_helper' - -RSpec.describe RegistrantChangeExpiredEmailJob do - describe '#run' do - let(:domain) { instance_double(Domain, - id: 1, - name: 'test.com', - new_registrant_email: 'new-registrant@test.com', - registrar: 'registrar', - registrant: 'registrant') - } - let(:message) { instance_double(ActionMailer::MessageDelivery) } - - before :example do - expect(Domain).to receive(:find).and_return(domain) - end - - after :example do - domain_id = 1 - described_class.enqueue(domain_id) - end - - it 'creates log record' do - log_message = 'Send RegistrantChangeMailer#expired email for domain test.com (#1) to new-registrant@test.com' - - allow(RegistrantChangeMailer).to receive(:expired).and_return(message) - allow(message).to receive(:deliver_now) - - expect(Rails.logger).to receive(:info).with(log_message) - end - - it 'sends email' do - expect(RegistrantChangeMailer).to receive(:expired).with(domain: domain, - registrar: 'registrar', - registrant: 'registrant') - .and_return(message) - expect(message).to receive(:deliver_now) - end - end -end diff --git a/spec/lib/validators/e164.rb b/spec/lib/validators/e164.rb deleted file mode 100644 index bfb4914a3..000000000 --- a/spec/lib/validators/e164.rb +++ /dev/null @@ -1,29 +0,0 @@ -# https://en.wikipedia.org/wiki/E.164 - -RSpec.shared_examples 'e164' do - describe 'validation' do - it 'rejects invalid format' do - model.send("#{attribute}=", '+.1') - model.validate - expect(model.errors).to be_added(attribute, :invalid) - end - - it 'rejects longer than max length' do - model.send("#{attribute}=", '1' * 18) - model.validate - expect(model.errors).to be_added(attribute, :too_long, count: 17) - end - - it 'accepts valid format' do - model.send("#{attribute}=", '+123.4') - model.validate - expect(model.errors).to_not be_added(attribute, :invalid) - end - - it 'accepts max length' do - model.send("#{attribute}=", '1' * 17) - model.validate - expect(model.errors).to_not be_added(attribute, :too_long, count: 17) - end - end -end diff --git a/spec/lib/validators/email_validator_spec.rb b/spec/lib/validators/email_validator_spec.rb deleted file mode 100644 index ecaadc8a7..000000000 --- a/spec/lib/validators/email_validator_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -require 'spec_helper' - -RSpec.describe EmailValidator do - describe '#valid?' do - subject(:valid) { described_class.new(email).valid? } - - context 'when email is valid' do - let(:email) { 'test@test.com' } - - it 'returns truthy' do - expect(valid).to be_truthy - end - end - - context 'when email is invalid' do - let(:email) { 'invalid' } - - it 'returns falsey' do - expect(valid).to be_falsey - end - end - end -end diff --git a/spec/lib/validators/iso31661_alpha2.rb b/spec/lib/validators/iso31661_alpha2.rb deleted file mode 100644 index 618a68cfb..000000000 --- a/spec/lib/validators/iso31661_alpha2.rb +++ /dev/null @@ -1,17 +0,0 @@ -# https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 - -RSpec.shared_examples 'iso31661_alpha2' do - describe 'validation' do - it 'rejects invalid' do - model.send("#{attribute}=", 'invalid') - model.validate - expect(model.errors).to be_added(attribute, :invalid_iso31661_alpha2) - end - - it 'accepts valid' do - model.send("#{attribute}=", 'US') - model.validate - expect(model.errors).to_not be_added(attribute, :invalid_iso31661_alpha2) - end - end -end diff --git a/spec/lib/validators/iso8601.rb b/spec/lib/validators/iso8601.rb deleted file mode 100644 index 78d8f2c4a..000000000 --- a/spec/lib/validators/iso8601.rb +++ /dev/null @@ -1,17 +0,0 @@ -# https://en.wikipedia.org/wiki/ISO_8601 - -RSpec.shared_examples 'iso8601' do - describe 'validation' do - it 'rejects invalid' do - model.send("#{attribute}=", '2010-07-0') - model.validate - expect(model.errors).to be_added(attribute, :invalid_iso8601_date) - end - - it 'accepts valid' do - model.send("#{attribute}=", '2010-07-05') - model.validate - expect(model.errors).to_not be_added(attribute, :invalid_iso8601_date) - end - end -end diff --git a/spec/models/account_activity_spec.rb b/spec/models/account_activity_spec.rb deleted file mode 100644 index 59e88c98b..000000000 --- a/spec/models/account_activity_spec.rb +++ /dev/null @@ -1,13 +0,0 @@ -require 'rails_helper' - -RSpec.describe AccountActivity do - describe 'account validation', db: false do - subject(:account_activity) { described_class.new } - - it 'rejects absent' do - account_activity.account = nil - account_activity.validate - expect(account_activity.errors).to have_key(:account) - end - end -end diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb deleted file mode 100644 index 46cef0b09..000000000 --- a/spec/models/account_spec.rb +++ /dev/null @@ -1,13 +0,0 @@ -require 'rails_helper' - -RSpec.describe Account do - describe 'registrar validation', db: false do - subject(:account) { described_class.new } - - it 'rejects absent' do - account.registrar = nil - account.validate - expect(account.errors).to have_key(:registrar) - end - end -end diff --git a/spec/models/admin_user_spec.rb b/spec/models/admin_user_spec.rb deleted file mode 100644 index 1cb8b5b12..000000000 --- a/spec/models/admin_user_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'rails_helper' - -RSpec.describe AdminUser do - context 'with valid attributes' do - before do - @admin_user = create(:admin_user) - end - - it 'should require password confirmation when changing password' do - @admin_user.valid?.should == true - @admin_user.password = 'not confirmed' - @admin_user.valid? - @admin_user.errors.full_messages.should match_array(["Password confirmation doesn't match Password"]) - end - end - - describe '::min_password_length' do - it 'returns minimum password length' do - expect(described_class.min_password_length).to eq(8) - end - end -end diff --git a/spec/models/api_user_spec.rb b/spec/models/api_user_spec.rb deleted file mode 100644 index e27cc8771..000000000 --- a/spec/models/api_user_spec.rb +++ /dev/null @@ -1,114 +0,0 @@ -require 'rails_helper' - -RSpec.describe ApiUser do - context 'with invalid attribute' do - before do - @api_user = ApiUser.new - end - - it 'should not be valid' do - @api_user.valid? - @api_user.errors.full_messages.should match_array([ - "Password Password is missing", - "Password is too short (minimum is #{ApiUser.min_password_length} characters)", - "Registrar Registrar is missing", - "Username Username is missing", - "Roles is missing" - ]) - end - - it 'should be active by default' do - @api_user.active.should == true - end - end - - context 'with valid attributes' do - before do - @api_user = create(:api_user) - end - - it 'should be valid' do - @api_user.valid? - @api_user.errors.full_messages.should match_array([]) - end - - it 'should be valid twice' do - @api_user = create(:api_user) - @api_user.valid? - @api_user.errors.full_messages.should match_array([]) - end - end - - describe '::min_password_length', db: false do - it 'returns minimum password length' do - expect(described_class.min_password_length).to eq(6) - end - end - - describe '#linked_users' do - it 'returns users with the same identity code' do - api_user = create(:api_user, id: 1, identity_code: 'test') - create(:api_user, id: 2, identity_code: 'test') - - expect(api_user.linked_users.ids).to include(2) - end - - it 'does not return users with another identity code' do - api_user = create(:api_user, id: 1, identity_code: 'test') - create(:api_user, id: 2, identity_code: 'another') - - expect(api_user.linked_users.ids).to_not include(2) - end - - it 'does not return itself' do - api_user = create(:api_user) - expect(api_user.linked_users).to be_empty - end - - it 'returns none if identity code is absent' do - api_user = create(:api_user, identity_code: nil) - create(:api_user, identity_code: nil) - - expect(api_user.linked_users).to be_empty - end - - it 'returns none if identity code is empty' do - api_user = create(:api_user, identity_code: '') - create(:api_user, identity_code: '') - - expect(api_user.linked_users).to be_empty - end - end - - describe '#linked_with?', db: false do - it 'returns true if identity codes match' do - api_user = described_class.new(identity_code: 'test') - another_api_user = described_class.new(identity_code: 'test') - - expect(api_user.linked_with?(another_api_user)).to be true - end - - it 'returns false if identity codes do not match' do - api_user = described_class.new(identity_code: 'test') - another_api_user = described_class.new(identity_code: 'another-test') - - expect(api_user.linked_with?(another_api_user)).to be false - end - end - - describe '#login', db: false do - it 'is alias to #username' do - user = described_class.new(username: 'test-username') - expect(user.login).to eq('test-username') - end - end - - describe '#registrar_name', db: false do - it 'delegates to registrar' do - registrar = Registrar.new(name: 'test name') - user = described_class.new(registrar: registrar) - - expect(user.registrar_name).to eq('test name') - end - end -end diff --git a/spec/models/authorization/restricted_ip_spec.rb b/spec/models/authorization/restricted_ip_spec.rb deleted file mode 100644 index b432d46e4..000000000 --- a/spec/models/authorization/restricted_ip_spec.rb +++ /dev/null @@ -1,98 +0,0 @@ -require 'rails_helper' - -RSpec.describe Authorization::RestrictedIP do - describe '::enabled?', db: true, settings: false do - before do - @original_registrar_ip_whitelist_enabled = Setting.registrar_ip_whitelist_enabled - end - - after do - Setting.registrar_ip_whitelist_enabled = @original_registrar_ip_whitelist_enabled - end - - context 'when "registrar_ip_whitelist_enabled" is true' do - before do - Setting.registrar_ip_whitelist_enabled = true - end - - specify do - expect(described_class).to be_enabled - end - end - - context 'when "registrar_ip_whitelist_enabled" is false' do - specify do - expect(described_class).to_not be_enabled - end - end - end - - describe '#can_access_registrar_area?', db: true do - let(:registrar) { create(:registrar) } - subject(:allowed) { described_class.new('127.0.0.1').can_access_registrar_area?(registrar) } - - context 'when enabled' do - before do - allow(described_class).to receive(:enabled?).and_return(true) - end - - context 'when ip is whitelisted', db: true do - let!(:white_ip) { create(:white_ip, registrar: registrar, ipv4: '127.0.0.1', interfaces: [WhiteIp::REGISTRAR]) } - - specify do - expect(allowed).to be true - end - end - - context 'when ip is not whitelisted' do - specify do - expect(allowed).to be false - end - end - end - - context 'when disabled' do - before do - allow(described_class).to receive(:enabled?).and_return(false) - end - - specify do - expect(allowed).to be true - end - end - end - - describe '#can_access_registrar_area_sign_in_page?' do - subject(:allowed) { described_class.new('127.0.0.1').can_access_registrar_area_sign_in_page? } - - context 'when enabled' do - before do - allow(described_class).to receive(:enabled?).and_return(true) - end - - context 'when ip is whitelisted', db: true do - let!(:white_ip) { create(:white_ip, ipv4: '127.0.0.1', interfaces: [WhiteIp::REGISTRAR]) } - - specify do - expect(allowed).to be true - end - end - - context 'when ip is not whitelisted' do - specify do - expect(allowed).to be false - end - end - end - - context 'when disabled' do - before do - allow(described_class).to receive(:enabled?).and_return(false) - end - - specify do - expect(allowed).to be true - end - end - end -end diff --git a/spec/models/billing/price_spec.rb b/spec/models/billing/price_spec.rb deleted file mode 100644 index 2854fb6b6..000000000 --- a/spec/models/billing/price_spec.rb +++ /dev/null @@ -1,180 +0,0 @@ -require 'rails_helper' - -RSpec.describe Billing::Price do - it { is_expected.to monetize(:price) } - it { is_expected.to alias_attribute(:effect_time, :valid_from) } - it { is_expected.to alias_attribute(:expire_time, :valid_to) } - - describe '::operation_categories', db: false do - it 'returns operation categories' do - categories = %w[create renew] - expect(described_class.operation_categories).to eq(categories) - end - end - - describe '::durations', db: false do - it 'returns durations' do - durations = [ - '3 mons', - '6 mons', - '9 mons', - '1 year', - '2 years', - '3 years', - '4 years', - '5 years', - '6 years', - '7 years', - '8 years', - '9 years', - '10 years', - ] - - expect(described_class.durations).to eq(durations) - end - end - - describe '::statuses', db: false do - it 'returns statuses' do - expect(described_class.statuses).to eq(%w[upcoming effective expired]) - end - end - - describe '::upcoming' do - before :example do - travel_to Time.zone.parse('05.07.2010 00:00') - - create(:price, id: 1, effect_time: Time.zone.parse('05.07.2010 00:00')) - create(:price, id: 2, effect_time: Time.zone.parse('05.07.2010 00:01')) - end - - it 'returns upcoming' do - expect(described_class.upcoming.ids).to eq([2]) - end - end - - describe '::effective' do - before :example do - travel_to Time.zone.parse('05.07.2010 00:00') - - create(:price, id: 1, effect_time: '05.07.2010 00:01', expire_time: '05.07.2010 00:02') - create(:price, id: 2, effect_time: '05.07.2010 00:00', expire_time: '05.07.2010 00:01') - create(:price, id: 3, effect_time: '05.07.2010 00:00', expire_time: nil) - create(:price, id: 4, effect_time: '04.07.2010', expire_time: '04.07.2010 23:59') - end - - it 'returns effective' do - expect(described_class.effective.ids).to eq([2, 3]) - end - end - - describe 'zone validation', db: false do - subject(:price) { described_class.new } - - it 'rejects absent' do - price.zone = nil - price.validate - expect(price.errors).to have_key(:zone) - end - end - - describe 'price validation', db: false do - subject(:price) { described_class.new } - - it 'rejects absent' do - price.price = nil - price.validate - expect(price.errors).to have_key(:price) - end - - it 'rejects negative' do - price.price = -1 - price.validate - expect(price.errors).to have_key(:price) - end - - it 'accepts zero' do - price.price = 0 - price.validate - expect(price.errors).to_not have_key(:price) - end - - it 'accepts greater than zero' do - price.price = 1 - price.validate - expect(price.errors).to_not have_key(:price) - end - - it 'accepts fraction' do - price.price = "1#{I18n.t('number.currency.format.separator')}5" - price.validate - expect(price.errors).to_not have_key(:price) - end - end - - describe 'duration validation', db: false do - subject(:price) { described_class.new } - - it 'rejects absent' do - price.duration = nil - price.validate - expect(price.errors).to have_key(:duration) - end - - it 'rejects invalid' do - price.duration = 'invalid' - price.validate - expect(price.errors).to have_key(:duration) - end - - it 'accepts valid' do - price.duration = described_class.durations.first - price.validate - expect(price.errors).to_not have_key(:duration) - end - end - - describe 'operation category validation', db: false do - subject(:price) { described_class.new } - - it 'rejects absent' do - price.operation_category = nil - price.validate - expect(price.errors).to have_key(:operation_category) - end - - it 'rejects invalid' do - price.operation_category = 'invalid' - price.validate - expect(price.errors).to have_key(:operation_category) - end - - it 'accepts valid' do - price.operation_category = described_class.operation_categories.first - price.validate - expect(price.errors).to_not have_key(:operation_category) - end - end - - describe '#name', db: false do - let(:price) { described_class.new } - - before :example do - allow(price).to receive(:operation_category).and_return('category') - allow(price).to receive(:zone_name).and_return('zone') - end - - it 'returns operation_category and zone name' do - expect(price.name).to eq('category zone') - end - end - - describe '#zone_name', db: false do - let(:price) { described_class.new(zone: zone) } - let(:zone) { build_stubbed(:zone, origin: 'test') } - - it 'returns zone name' do - expect(price.zone_name).to eq('test') - end - end -end diff --git a/spec/models/concerns/billing/price/expirable_spec.rb b/spec/models/concerns/billing/price/expirable_spec.rb deleted file mode 100644 index 2180af432..000000000 --- a/spec/models/concerns/billing/price/expirable_spec.rb +++ /dev/null @@ -1,55 +0,0 @@ -require 'rails_helper' - -RSpec.describe Billing::Price do - describe '::expired' do - before :example do - travel_to Time.zone.parse('05.07.2010 00:00') - - create(:price, id: 1, expire_time: Time.zone.parse('04.07.2010 23:59')) - create(:price, id: 2, expire_time: Time.zone.parse('05.07.2010 00:00')) - create(:price, id: 3, expire_time: Time.zone.parse('05.07.2010 00:01')) - end - - it 'returns prices with expire time in the past ' do - expect(described_class.expired.ids).to eq([1]) - end - end - - describe '#expire', db: false do - let(:price) { described_class.new(expire_time: Time.zone.parse('06.07.2010')) } - - before :example do - travel_to Time.zone.parse('05.07.2010 00:00') - end - - it 'expires price' do - expect { price.expire }.to change { price.expired? }.from(false).to(true) - end - end - - describe '#expired?', db: false do - subject(:expired) { domain.expired? } - - before :example do - travel_to Time.zone.parse('05.07.2010 00:00') - end - - context 'when expire time is in the past' do - let(:domain) { described_class.new(expire_time: Time.zone.parse('04.07.2010 23:59')) } - - specify { expect(expired).to be true } - end - - context 'when expire time is now' do - let(:domain) { described_class.new(expire_time: Time.zone.parse('05.07.2010 00:00')) } - - specify { expect(expired).to be false } - end - - context 'when expire time is in the future' do - let(:domain) { described_class.new(expire_time: Time.zone.parse('05.07.2010 00:01')) } - - specify { expect(expired).to be false } - end - end -end diff --git a/spec/models/concerns/domain/activatable_spec.rb b/spec/models/concerns/domain/activatable_spec.rb deleted file mode 100644 index aeb5b0bfd..000000000 --- a/spec/models/concerns/domain/activatable_spec.rb +++ /dev/null @@ -1,68 +0,0 @@ -require 'rails_helper' - -RSpec.describe Domain, db: false do - describe '#active?' do - context 'when :statuses does not contain :inactive' do - let(:domain) { described_class.new(statuses: []) } - - it 'returns true' do - expect(domain.active?).to be true - end - end - - context 'when :statuses contains :inactive' do - let(:domain) { described_class.new(statuses: [DomainStatus::INACTIVE]) } - - it 'returns false' do - expect(domain.active?).to be false - end - end - end - - describe '#inactive?' do - context 'when :statuses contains :inactive' do - let(:domain) { described_class.new(statuses: [DomainStatus::INACTIVE]) } - - it 'returns true' do - expect(domain.inactive?).to be true - end - end - - context 'when :statuses does not contain :inactive' do - let(:domain) { described_class.new(statuses: []) } - - it 'returns false' do - expect(domain.inactive?).to be false - end - end - end - - describe '#activate' do - let(:domain) { described_class.new(statuses: [DomainStatus::INACTIVE]) } - - it 'activates domain' do - domain.activate - expect(domain).to be_active - end - end - - describe '#deactivate' do - context 'when active' do - let(:domain) { described_class.new } - - it 'deactivates domain' do - domain.deactivate - expect(domain).to be_inactive - end - end - - context 'when inactive' do - let(:domain) { described_class.new(statuses: [DomainStatus::INACTIVE]) } - - it 'does not add :inactive status' do - domain.deactivate - expect(domain.statuses).to eq([DomainStatus::INACTIVE]) - end - end - end -end diff --git a/spec/models/concerns/domain/expirable_spec.rb b/spec/models/concerns/domain/expirable_spec.rb deleted file mode 100644 index 242d9818a..000000000 --- a/spec/models/concerns/domain/expirable_spec.rb +++ /dev/null @@ -1,65 +0,0 @@ -require 'rails_helper' - -RSpec.describe Domain, db: false do - it { is_expected.to alias_attribute(:expire_time, :valid_to) } - - describe '::expired', db: true do - before :example do - travel_to Time.zone.parse('05.07.2010 00:00') - - create(:zone, origin: 'ee') - - create(:domain, id: 1, expire_time: Time.zone.parse('04.07.2010 23:59')) - create(:domain, id: 2, expire_time: Time.zone.parse('05.07.2010 00:00')) - create(:domain, id: 3, expire_time: Time.zone.parse('05.07.2010 00:01')) - end - - it 'returns expired domains' do - expect(described_class.expired.ids).to eq([1, 2]) - end - end - - describe '#registered?' do - let(:domain) { described_class.new } - - context 'when not expired' do - before :example do - expect(domain).to receive(:expired?).and_return(false) - end - - specify { expect(domain).to be_registered } - end - - context 'when expired' do - before :example do - expect(domain).to receive(:expired?).and_return(true) - end - - specify { expect(domain).to_not be_registered } - end - end - - describe '#expired?' do - before :example do - travel_to Time.zone.parse('05.07.2010 00:00') - end - - context 'when :expire_time is in the past' do - let(:domain) { described_class.new(expire_time: Time.zone.parse('04.07.2010 23:59')) } - - specify { expect(domain).to be_expired } - end - - context 'when :expire_time is now' do - let(:domain) { described_class.new(expire_time: Time.zone.parse('05.07.2010 00:00')) } - - specify { expect(domain).to be_expired } - end - - context 'when :expire_time is in the future' do - let(:domain) { described_class.new(expire_time: Time.zone.parse('05.07.2010 00:01')) } - - specify { expect(domain).to_not be_expired } - end - end -end diff --git a/spec/models/contact/contact_phone_spec.rb b/spec/models/contact/contact_phone_spec.rb deleted file mode 100644 index cc1ecbec0..000000000 --- a/spec/models/contact/contact_phone_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -require 'rails_helper' -require 'lib/validators/e164' - -RSpec.describe Contact do - let(:contact) { described_class.new } - - describe 'phone', db: false do - it_behaves_like 'e164' do - let(:model) { contact } - let(:attribute) { :phone } - end - end - - describe 'phone validation', db: false do - it 'rejects absent' do - contact.phone = nil - contact.validate - expect(contact.errors).to be_added(:phone, :blank) - end - - it 'rejects all zeros in country code' do - contact.phone = '+000.1' - contact.validate - expect(contact.errors).to be_added(:phone, :invalid) - end - - it 'rejects all zeros in subscriber number' do - contact.phone = '+123.0' - contact.validate - expect(contact.errors).to be_added(:phone, :invalid) - end - end -end diff --git a/spec/models/contact/ident_spec.rb b/spec/models/contact/ident_spec.rb deleted file mode 100644 index d26f76d0f..000000000 --- a/spec/models/contact/ident_spec.rb +++ /dev/null @@ -1,227 +0,0 @@ -require 'active_model' -require 'lib/validators/iso31661_alpha2' -require 'lib/validators/iso8601' - -RSpec.describe Contact::Ident, db: false do - let(:ident) { described_class.new } - - describe 'country code' do - it_behaves_like 'iso31661_alpha2' do - let(:model) { ident } - let(:attribute) { :country_code } - end - end - - describe 'code validation' do - it 'rejects absent' do - ident.code = nil - ident.validate - expect(ident.errors).to be_added(:code, :blank) - end - - context 'when type is :birthday' do - let(:ident) { described_class.new(type: 'birthday') } - - it_behaves_like 'iso8601' do - let(:model) { ident } - let(:attribute) { :code } - end - end - - context 'when type is not :birthday' do - let(:ident) { described_class.new(type: 'priv') } - - it 'accepts any' do - ident.code = '%123456789%' - ident.validate - expect(ident.errors).to_not include(:code) - end - end - - context 'when country code is EE' do - context 'when type is :priv' do - let(:ident) { described_class.new(country_code: 'EE', type: 'priv') } - - it 'rejects invalid' do - ident.code = 'invalid' - ident.validate - expect(ident.errors).to be_added(:code, :invalid_national_id, country: 'Estonia') - end - - it 'accepts valid' do - ident.code = '47101010033' - ident.validate - expect(ident.errors).to_not be_added(:code, :invalid_national_id, country: 'Estonia') - end - end - - context 'when ident type is :org' do - let(:ident) { described_class.new(country_code: 'EE', type: 'org') } - - it 'rejects invalid' do - ident.code = '1' * 7 - ident.validate - expect(ident.errors).to be_added(:code, :invalid_reg_no, country: 'Estonia') - end - - it 'accepts valid length' do - ident.code = '1' * 8 - ident.validate - expect(ident.errors).to_not be_added(:code, :invalid_reg_no, country: 'Estonia') - end - end - end - - context 'when ident country code is not EE' do - let(:ident) { described_class.new(country_code: 'US') } - - it 'accepts any' do - ident.code = 'test-123456789' - ident.validate - expect(ident.errors).to_not include(:code) - end - end - - it 'translates :invalid_national_id error message' do - expect(ident.errors.generate_message(:code, :invalid_national_id, country: 'Germany')) - .to eq('does not conform to national identification number format of Germany') - end - - it 'translates :invalid_reg_no error message' do - expect(ident.errors.generate_message(:code, :invalid_reg_no, country: 'Germany')) - .to eq('does not conform to registration number format of Germany') - end - end - - describe 'type validation' do - before do - allow(described_class).to receive(:types).and_return(%w(valid)) - end - - it 'rejects absent' do - ident.type = nil - ident.validate - expect(ident.errors).to be_added(:type, :blank) - end - - it 'rejects invalid' do - ident.type = 'invalid' - ident.validate - expect(ident.errors).to be_added(:type, :inclusion) - end - - it 'accepts valid' do - ident.type = 'valid' - ident.validate - expect(ident.errors).to_not be_added(:type, :inclusion) - end - end - - describe 'country code validation' do - it 'rejects absent' do - ident.country_code = nil - ident.validate - expect(ident.errors).to be_added(:country_code, :blank) - end - end - - describe 'mismatch validation' do - let(:ident) { described_class.new(type: 'test', country_code: 'DE') } - - before do - mismatches = [Contact::Ident::MismatchValidator::Mismatch.new('test', Country.new('DE'))] - allow(Contact::Ident::MismatchValidator).to receive(:mismatches).and_return(mismatches) - end - - it 'rejects mismatched' do - ident.validate - expect(ident.errors).to be_added(:base, :mismatch, type: 'test', country: 'Germany') - end - - it 'accepts matched' do - ident.validate - expect(ident.errors).to_not be_added(:base, :mismatch, type: 'another-test', country: 'Germany') - end - - it 'translates :mismatch error message' do - expect(ident.errors.generate_message(:base, :mismatch, type: 'test', country: 'Germany')) - .to eq('Ident type "test" is invalid for Germany') - end - end - - describe '::types' do - it 'returns types' do - types = %w[ - org - priv - birthday - ] - - expect(described_class.types).to eq(types) - end - end - - describe '#birthday?' do - context 'when type is birthday' do - subject(:ident) { described_class.new(type: 'birthday') } - it { is_expected.to be_birthday } - end - - context 'when type is not birthday' do - subject(:ident) { described_class.new(type: 'priv') } - it { is_expected.to_not be_birthday } - end - end - - describe '#national_id?' do - context 'when type is priv' do - subject(:ident) { described_class.new(type: 'priv') } - it { is_expected.to be_national_id } - end - - context 'when type is not' do - subject(:ident) { described_class.new(type: 'org') } - it { is_expected.to_not be_national_id } - end - end - - describe '#reg_no?' do - context 'when type is birthday' do - subject(:ident) { described_class.new(type: 'org') } - it { is_expected.to be_reg_no } - end - - context 'when type is not birthday' do - subject(:ident) { described_class.new(type: 'priv') } - it { is_expected.to_not be_reg_no } - end - end - - describe '#country' do - let(:ident) { described_class.new(country_code: 'US') } - - it 'returns country' do - expect(ident.country).to eq(Country.new('US')) - end - end - - describe '#==' do - let(:ident) { described_class.new(code: 'test', type: 'test', country_code: 'US') } - - context 'when code, type and country code are the same' do - let(:another_ident) { described_class.new(code: 'test', type: 'test', country_code: 'US') } - - it 'returns true' do - expect(ident).to eq(another_ident) - end - end - - context 'when code, type and country code are not the same' do - let(:another_ident) { described_class.new(code: 'another-test', type: 'test', country_code: 'US') } - - it 'returns false' do - expect(ident).to_not eq(another_ident) - end - end - end -end diff --git a/spec/models/contact_spec.rb b/spec/models/contact_spec.rb deleted file mode 100644 index cfcdad30e..000000000 --- a/spec/models/contact_spec.rb +++ /dev/null @@ -1,386 +0,0 @@ -require 'rails_helper' - -RSpec.describe Contact do - before :example do - create(:zone, origin: 'ee') - end - - context 'with invalid attribute' do - before :example do - @contact = Contact.new - end - - it 'should not have creator' do - @contact.creator.should == nil - end - - it 'should not have updater' do - @contact.updator.should == nil - end - - it 'should not accept long code' do - @contact.code = 'verylongcode' * 100 - @contact.valid? - @contact.errors[:code].should == ['Contact code is too long, max 100 characters'] - end - - it 'should not allow double status' do - contact = described_class.new(statuses: %w(ok ok)) - - contact.validate - - expect(contact.statuses).to eq(%w(ok)) - end - - it 'should have no related domain descriptions' do - @contact.related_domain_descriptions.should == {} - end - - it 'should fully validate email syntax for new records' do - @contact.email = 'not@correct' - @contact.valid? - @contact.errors[:email].should == ['Email is invalid'] - end - - it 'should have ident updated because the logic itself is dedicated for legacy contacts ' do - @contact.ident_updated_at.should_not == nil - end - end - - context 'with valid attributes' do - before :example do - @contact = create(:contact) - end - - it 'should not overwrite code' do - old_code = @contact.code - @contact.code = 'CID:REG1:should-not-overwrite-old-code-12345' - @contact.save.should == true - @contact.code.should == old_code - end - - it 'should have ok status by default' do - @contact.statuses.should == %w(ok) - end - - it 'should not remove ok status after save' do - @contact.statuses.should == %w(ok) - @contact.save - @contact.statuses.should == %w(ok) - end - - it 'should remove ok status when other non linked status present' do - contact = create(:contact) - contact.statuses = [Contact::SERVER_UPDATE_PROHIBITED] - contact.statuses.should == [Contact::SERVER_UPDATE_PROHIBITED] # temp test - contact.save - contact.statuses.should == [Contact::SERVER_UPDATE_PROHIBITED] - end - - it 'should have code' do - registrar = create(:registrar, code: 'registrarcode') - - contact = build(:contact, registrar: registrar, code: 'contactcode') - contact.generate_code - contact.save! - - expect(contact.code).to eq('REGISTRARCODE:CONTACTCODE') - end - - it 'should save status notes' do - contact = create(:contact) - contact.statuses = ['serverDeleteProhibited', 'serverUpdateProhibited'] - contact.status_notes_array = [nil, 'update manually turned off'] - contact.status_notes['serverDeleteProhibited'].should == nil - contact.status_notes['serverUpdateProhibited'].should == 'update manually turned off' - contact.status_notes['someotherstatus'].should == nil - end - - it 'should have ident already updated because the logic itself is only for legacy contacts' do - @contact.ident_updated_at.should_not == nil - end - - it 'should have not update ident updated at when initializing old contact' do - # creating a legacy contact - contact = create(:contact) - contact.update_column(:ident_updated_at, nil) - - Contact.find(contact.id).ident_updated_at.should == nil - end - - context 'as birthday' do - before do - @domain = create(:domain) - end - - it 'should have related domain descriptions hash' do - contact = @domain.registrant - contact.reload # somehow it registrant_domains are empty? - contact.related_domain_descriptions.should == { "#{@domain.name}" => [:registrant] } - end - - it 'should have related domain descriptions hash when find directly' do - contact = @domain.registrant - Contact.find(contact.id).related_domain_descriptions.should == { "#{@domain.name}" => [:registrant] } - end - - it 'should have related domain descriptions hash' do - contact = @domain.contacts.first - contact.related_domain_descriptions.should == { "#{@domain.name}" => [:admin] } - end - - it 'should fully validate email syntax for old records' do - old = @contact.email - @contact.email = 'legacy@support-not-correct' - @contact.valid? - @contact.errors[:email].should == ['Email is invalid'] - @contact.email = old - end - end - - context 'with callbacks' do - context 'after create' do - it 'should not allow to use same code' do - registrar = create(:registrar, code: 'FIXED') - - create(:contact, - registrar: registrar, - code: 'FIXED:new-code') - @contact = build(:contact, - registrar: registrar, - code: 'FIXED:new-code') - - @contact.validate - - expect(@contact.errors).to have_key(:code) - end - - it 'should allow supported code format' do - @contact = build(:contact, code: 'CID:REG1:12345', registrar: create(:registrar, code: 'FIXED')) - @contact.valid? - @contact.errors.full_messages.should == [] - end - - it 'should not allow unsupported characters in code' do - @contact = build(:contact, code: 'unsupported!ÄÖÜ~?', registrar: create(:registrar, code: 'FIXED')) - @contact.valid? - @contact.errors.full_messages.should == ['Code is invalid'] - end - - it 'should generate code if empty code is given' do - @contact = build(:contact, code: '') - @contact.generate_code - @contact.save! - @contact.code.should_not == '' - end - - it 'should not ignore empty spaces as code and generate new one' do - @contact = build(:contact, code: ' ', registrar: create(:registrar, code: 'FIXED')) - @contact.generate_code - @contact.valid?.should == true - @contact.code.should =~ /FIXED:..../ - end - end - end - end -end - -RSpec.describe Contact do - it { is_expected.to alias_attribute(:kind, :ident_type) } - - describe '::emails' do - before :example do - expect(described_class).to receive(:pluck).with(:email).and_return('emails') - end - - it 'returns emails' do - expect(described_class.emails).to eq('emails') - end - end - - describe '::address_processing?' do - before do - Setting.address_processing = 'test' - end - - it 'returns setting value' do - expect(described_class.address_processing?).to eq('test') - end - end - - describe '::address_attribute_names', db: false do - it 'returns address attributes' do - attributes = %w( - city - street - zip - country_code - state - ) - expect(described_class.address_attribute_names).to eq(attributes) - end - end - - describe 'registrar validation', db: false do - let(:contact) { described_class.new } - - it 'rejects absent' do - contact.registrar = nil - contact.validate - expect(contact.errors).to have_key(:registrar) - end - end - - describe 'address validation', db: false do - let(:contact) { described_class.new } - subject(:errors) { contact.errors } - - required_attributes = %i(street city zip country_code) - - context 'when address processing is enabled' do - before do - allow(described_class).to receive(:address_processing?).and_return(true) - end - - required_attributes.each do |attr_name| - it "rejects absent #{attr_name}" do - contact.send("#{attr_name}=", nil) - contact.validate - expect(errors).to have_key(attr_name) - end - end - end - - context 'when address processing is disabled' do - before do - allow(described_class).to receive(:address_processing?).and_return(false) - end - - required_attributes.each do |attr_name| - it "accepts absent #{attr_name}" do - contact.send("#{attr_name}=", nil) - contact.validate - expect(errors).to_not have_key(attr_name) - end - end - end - end - - describe 'country code validation', db: false do - let(:contact) { described_class.new(country_code: 'test') } - - it 'rejects invalid' do - contact.country_code = 'invalid' - contact.validate - expect(contact.errors).to have_key(:country_code) - end - end - - describe 'identifier validation', db: false do - let(:contact) { described_class.new } - - it 'rejects invalid' do - ident = Contact::Ident.new - ident.validate - contact.identifier = ident - contact.validate - - expect(contact.errors).to be_added(:identifier, :invalid) - end - - it 'accepts valid' do - ident = Contact::Ident.new(code: 'test', type: 'priv', country_code: 'US') - ident.validate - contact.identifier = ident - contact.validate - - expect(contact.errors).to_not be_added(:identifier, :invalid) - end - end - - describe '#remove_address' do - let(:contact) { described_class.new(city: 'test', - street: 'test', - zip: 'test', - country_code: 'test', - state: 'test') - } - subject(:address_removed) { contact.attributes.slice(*described_class.address_attribute_names).compact.empty? } - - it 'removes address attributes' do - contact.remove_address - expect(address_removed).to be_truthy - end - end - - describe '#reg_no' do - subject(:reg_no) { contact.reg_no } - - context 'when contact is legal entity' do - let(:contact) { build_stubbed(:contact_legal_entity, ident: '1234') } - - specify { expect(reg_no).to eq('1234') } - end - - context 'when contact is private entity' do - let(:contact) { build_stubbed(:contact_private_entity, ident: '1234') } - - specify { expect(reg_no).to be_nil } - end - end - - describe '#id_code' do - context 'when contact is private entity' do - let(:contact) { build_stubbed(:contact_private_entity, ident: '1234') } - - specify { expect(contact.id_code).to eq('1234') } - end - - context 'when contact is legal entity' do - let(:contact) { build_stubbed(:contact_legal_entity, ident: '1234') } - - specify { expect(contact.id_code).to be_nil } - end - end - - describe '#ident_country' do - let(:contact) { described_class.new(ident_country_code: 'US') } - - it 'returns ident country' do - expect(contact.ident_country).to eq(Country.new('US')) - end - end - - describe '#domain_names_with_roles' do - let(:contact) { create(:registrant) } - subject(:domain_names) { contact.domain_names_with_roles } - - it 'returns associated domains with roles' do - domain = create(:domain, registrant: contact, name: 'test.com') - domain.admin_domain_contacts << create(:admin_domain_contact, contact: contact) - domain.tech_domain_contacts << create(:tech_domain_contact, contact: contact) - - contact.reload - - expect(domain_names).to eq({ 'test.com' => %i[registrant admin_domain_contact tech_domain_contact].to_set }) - end - - it 'returns unique roles' do - domain = create(:domain, name: 'test.com') - 2.times { domain.admin_domain_contacts << create(:admin_domain_contact, contact: contact) } - - contact.reload - - expect(domain_names).to eq({ 'test.com' => %i[admin_domain_contact].to_set }) - end - end - - it 'normalizes ident country code', db: false do - contact = described_class.new - - contact.ident_country_code = 'ee' - contact.validate - - expect(contact.ident_country_code).to eq('EE') - end -end diff --git a/spec/models/depp/domain_spec.rb b/spec/models/depp/domain_spec.rb deleted file mode 100644 index c780e6a00..000000000 --- a/spec/models/depp/domain_spec.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'rails_helper' - -RSpec.describe Depp::Domain do - describe '::default_period', db: false, settings: false do - it 'returns default period' do - expect(described_class.default_period).to eq('1y') - end - end -end diff --git a/spec/models/dns/zone_spec.rb b/spec/models/dns/zone_spec.rb deleted file mode 100644 index a5d7861e6..000000000 --- a/spec/models/dns/zone_spec.rb +++ /dev/null @@ -1,102 +0,0 @@ -require 'rails_helper' - -RSpec.describe DNS::Zone do - describe '::origins' do - before :example do - expect(described_class).to receive(:pluck).with(:origin).and_return('origins') - end - - it 'returns origins' do - expect(described_class.origins).to eq('origins') - end - end - - describe 'validation' do - let(:zone) { described_class.new } - - required_attributes = %i[ - origin - ttl - refresh - retry - expire - minimum_ttl - email - master_nameserver - ] - - required_attributes.each do |attr_name| - it "rejects absent #{attr_name}", db: false do - zone.send("#{attr_name}=", nil) - zone.validate - expect(zone.errors).to have_key(attr_name) - end - end - - integer_attributes = %i[ - ttl - refresh - retry - expire - minimum_ttl - ] - - integer_attributes.each do |attr_name| - it "rejects non-integer #{attr_name}", db: false do - zone.send("#{attr_name}=", 'test') - zone.validate - expect(zone.errors).to have_key(attr_name) - end - - it "accepts integer #{attr_name}", db: false do - zone.send("#{attr_name}=", '1') - zone.validate - expect(zone.errors).to_not have_key(attr_name) - end - end - end - - describe '#used?', db: false do - let!(:zone) { described_class.new } - - context 'when domain uses zone' do - before :example do - allow(Domain).to receive(:uses_zone?).and_return(true) - end - - specify { expect(zone).to be_used } - end - - context 'when domain does not use zone' do - before :example do - allow(Domain).to receive(:uses_zone?).and_return(false) - end - - specify { expect(zone).to_not be_used } - end - end - - describe 'deletion', settings: false do - let!(:zone) { create(:zone) } - - context 'when zone is unused' do - before :example do - allow(zone).to receive(:used?).and_return(false) - end - - it 'is allowed' do - expect { zone.destroy }.to change { described_class.count }.from(1).to(0) - end - end - - context 'when zone is used' do - before :example do - allow(zone).to receive(:used?).and_return(true) - end - - it 'is disallowed' do - expect { zone.destroy }.to_not change { described_class.count } - end - end - end -end diff --git a/spec/models/dnskey_spec.rb b/spec/models/dnskey_spec.rb deleted file mode 100644 index d21968214..000000000 --- a/spec/models/dnskey_spec.rb +++ /dev/null @@ -1,102 +0,0 @@ -require 'rails_helper' - -describe Dnskey do - before :example do - Setting.ds_algorithm = 2 - Setting.ds_data_allowed = true - Setting.ds_data_with_key_allowed = true - Setting.key_data_allowed = true - - Setting.dnskeys_min_count = 0 - Setting.dnskeys_max_count = 9 - Setting.ns_min_count = 2 - Setting.ns_max_count = 11 - - Setting.transfer_wait_time = 0 - - Setting.admin_contacts_min_count = 1 - Setting.admin_contacts_max_count = 10 - Setting.tech_contacts_min_count = 0 - Setting.tech_contacts_max_count = 10 - - Setting.client_side_status_editing_enabled = true - - create(:zone, origin: 'ee') - end - - context 'with invalid attribute' do - before :example do - @dnskey = Dnskey.new - end - - it 'should not be valid' do - @dnskey.valid? - @dnskey.errors.full_messages.should match_array([ - ]) - end - end - - context 'with valid attributes' do - before :example do - @dnskey = create(:dnskey, - alg: 8, - flags: 257, - protocol: 3, - public_key: 'AwEAAaOf5+lz3ftsL+0CCvfJbhUF/NVsNh8BKo61oYs5fXVbuWDiH872 '\ - 'LC8uKDO92TJy7Q4TF9XMAKMMlf1GMAxlRspD749SOCTN00sqfWx1OMTu '\ - 'a28L1PerwHq7665oDJDKqR71btcGqyLKhe2QDvCdA0mENimF1NudX1BJ '\ - 'DDFi6oOZ0xE/0CuveB64I3ree7nCrwLwNs56kXC4LYoX3XdkOMKiJLL/ '\ - 'MAhcxXa60CdZLoRtTEW3z8/oBq4hEAYMCNclpbd6y/exScwBxFTdUfFk '\ - 'KsdNcmvai1lyk9vna0WQrtpYpHKMXvY9LFHaJxCOLR4umfeQ42RuTd82 lqfU6ClMeXs=', - ds_digest_type: 2) - end - - it 'should be valid' do - @dnskey.valid? - @dnskey.errors.full_messages.should match_array([]) - end - - it 'should be valid twice' do - @dnskey = create(:dnskey) - @dnskey.valid? - @dnskey.errors.full_messages.should match_array([]) - end - - it 'generates correct DS digest and DS key tag for ria.ee' do - d = create(:domain, name: 'ria.ee', dnskeys: [@dnskey]) - dk = d.dnskeys.last - - dk.generate_digest - dk.ds_digest.should == '0B62D1BC64EFD1EE652FB102BDF1011BF514CCD9A1A0CFB7472AEA3B01F38C92' - dk.ds_key_tag.should == '30607' - end - - it 'generates correct DS digest and DS key tag for emta.ee' do - d = create(:domain, name: 'emta.ee', dnskeys: [@dnskey]) - - dk = d.dnskeys.last - - pk = 'AwEAAfB9jK8rj/FAdE3t9bYXiTLpelwlgUyxbHEtvMvhdxs+yHv0h9fE '\ - '710u94LPAeVmXumT6SZPsoo+ALKdmTexkcU9DGQvb2+sPfModBKM/num '\ - 'rScUw1FBe3HwRa9SqQpgpnCjIt0kEVKHAQdLOP86YznSA9uHAg9TTJuT '\ - 'LkUtgtmwNAVFr6/mG+smE1v5NbxPccsFwVTA/T1IyaI4Z48VGCP2WNro '\ - 'R7P6vet1gWhssirnnVYnur8DwWuMJ89o/HjzXeiEGUB8k5SOX+//67FN '\ - 'm8Zs+1ObuAfY8xAHe0L5bxluEbh1T1ARp41QX77EMKVbkcSj7nuBeY8H '\ - 'KiN8HsTvmZyDbRAQQaAJi68qOXsUIoQcpn89PoNoc60F7WlueA6ExSGX '\ - 'KMWIH6nfLXFgidoZ6HxteyUUnZbHEdULjpAoCRuUDjjUnUgFS7eRANfw '\ - 'RCcu9aLziMDp4UU61zVjtmQ7xn3G2W2+2ycqn/vEl/yFyBmHZ+7stpoC '\ - 'd6NTZUn4/ellYSm9lx/vaXdPSinARpYMWtU79Hu/VRifaCQjYkBGAMwK '\ - 'DshX4yJPjza/bqo0XV4WHj1szDFHe0tLN7g1Ojwtf5FR0zyHU3FN9uUa '\ - 'y8a+dowd/fqOQA1jXR04g2PIfFYe0VudCEpmxSV9YDoqjghHeIKUX7Jn '\ - 'KiHL5gk404S5a/Bv' - - dk.public_key = pk - - dk.save - dk.ds_digest.should == 'D7045D3C2EF7332409A132D935C8E2834A2AAB769B35BC370FA68C9445398288' - dk.ds_key_tag.should == '31051' - - dk.public_key.should == pk - end - end -end diff --git a/spec/models/domain_contact_spec.rb b/spec/models/domain_contact_spec.rb deleted file mode 100644 index f5476c49b..000000000 --- a/spec/models/domain_contact_spec.rb +++ /dev/null @@ -1,95 +0,0 @@ -require 'rails_helper' - -describe DomainContact do - before :example do - @api_user = create(:domain_contact) - end - - context 'with invalid attribute' do - before :example do - @domain_contact = DomainContact.new - end - - it 'should not be valid' do - @domain_contact.valid? - @domain_contact.errors.full_messages.should match_array([ - "Contact Contact was not found" - ]) - end - - it 'should not have creator' do - @domain_contact.creator.should == nil - end - - it 'should not have updater' do - @domain_contact.updator.should == nil - end - - it 'should not have any name' do - @domain_contact.name.should == '' - end - end - - context 'with valid attributes' do - before :example do - @domain_contact = create(:domain_contact, type: 'TechDomainContact') - end - - it 'should be valid' do - @domain_contact.valid? - @domain_contact.errors.full_messages.should match_array([]) - end - - it 'should be valid twice' do - @domain_contact = create(:domain_contact) - @domain_contact.valid? - @domain_contact.errors.full_messages.should match_array([]) - end - - it 'should have Tech name' do - @domain_contact.name.should == 'Tech' - end - end - - context 'with valid attributes with tech domain contact' do - before :example do - @domain_contact = create(:tech_domain_contact) - end - - it 'should be valid' do - @domain_contact.valid? - @domain_contact.errors.full_messages.should match_array([]) - end - - it 'should be valid twice' do - @domain_contact = create(:tech_domain_contact) - @domain_contact.valid? - @domain_contact.errors.full_messages.should match_array([]) - end - - it 'should have Tech name' do - @domain_contact.name.should == 'Tech' - end - end - - context 'with valid attributes with admin domain contact' do - before :example do - @domain_contact = create(:admin_domain_contact) - end - - it 'should be valid' do - @domain_contact.valid? - @domain_contact.errors.full_messages.should match_array([]) - end - - it 'should be valid twice' do - @domain_contact = create(:admin_domain_contact) - @domain_contact.valid? - @domain_contact.errors.full_messages.should match_array([]) - end - - it 'should have Tech name' do - @domain_contact.name.should == 'Admin' - end - end -end diff --git a/spec/models/domain_cron_spec.rb b/spec/models/domain_cron_spec.rb deleted file mode 100644 index 0d25e375b..000000000 --- a/spec/models/domain_cron_spec.rb +++ /dev/null @@ -1,41 +0,0 @@ -require 'rails_helper' - -RSpec.describe DomainCron do - it 'should expire domains' do - create(:zone, origin: 'ee') - @domain = create(:domain) - - Setting.expire_warning_period = 1 - Setting.redemption_grace_period = 1 - - described_class.start_expire_period - @domain.statuses.include?(DomainStatus::EXPIRED).should == false - - old_valid_to = Time.zone.now - 10.days - @domain.valid_to = old_valid_to - @domain.save - - described_class.start_expire_period - @domain.reload - @domain.statuses.include?(DomainStatus::EXPIRED).should == true - - described_class.start_expire_period - @domain.reload - @domain.statuses.include?(DomainStatus::EXPIRED).should == true - end - - it 'should start redemption grace period' do - create(:zone, origin: 'ee') - @domain = create(:domain) - - old_valid_to = Time.zone.now - 10.days - @domain.valid_to = old_valid_to - @domain.statuses = [DomainStatus::EXPIRED] - @domain.outzone_at, @domain.delete_date = nil, nil - @domain.save - - described_class.start_expire_period - @domain.reload - @domain.statuses.include?(DomainStatus::EXPIRED).should == true - end -end diff --git a/spec/models/domain_spec.rb b/spec/models/domain_spec.rb deleted file mode 100644 index ac424bcbe..000000000 --- a/spec/models/domain_spec.rb +++ /dev/null @@ -1,744 +0,0 @@ -require 'rails_helper' - -RSpec.describe Domain do - before :example do - Setting.ds_algorithm = 2 - Setting.ds_data_allowed = true - Setting.ds_data_with_key_allowed = true - Setting.key_data_allowed = true - - Setting.dnskeys_min_count = 0 - Setting.dnskeys_max_count = 9 - Setting.ns_min_count = 2 - Setting.ns_max_count = 11 - - Setting.transfer_wait_time = 0 - - Setting.admin_contacts_min_count = 1 - Setting.admin_contacts_max_count = 10 - Setting.tech_contacts_min_count = 0 - Setting.tech_contacts_max_count = 10 - - Setting.client_side_status_editing_enabled = true - - create(:zone, origin: 'ee') - create(:zone, origin: 'pri.ee') - create(:zone, origin: 'med.ee') - create(:zone, origin: 'fie.ee') - create(:zone, origin: 'com.ee') - end - - context 'with invalid attribute' do - before :example do - @domain = Domain.new - end - - it 'should not have whois body' do - @domain.whois_record.should == nil - end - - it 'should not be registrant update confirm ready' do - @domain.registrant_update_confirmable?('123').should == false - end - - it 'should not have pending update' do - @domain.pending_update?.should == false - end - - it 'should allow pending update' do - @domain.pending_update_prohibited?.should == false - end - - it 'should not have pending delete' do - @domain.pending_delete?.should == false - end - - it 'should allow pending delete' do - @domain.pending_delete_prohibited?.should == false - end - end - - context 'with valid attributes' do - before :example do - @domain = create(:domain) - end - - it 'should be valid' do - @domain.valid? - @domain.errors.full_messages.should match_array([]) - end - - it 'should be valid twice' do - @domain = create(:domain) - @domain.valid? - @domain.errors.full_messages.should match_array([]) - end - - it 'should validate uniqueness of tech contacts' do - same_contact = create(:contact, code: 'same_contact') - domain = create(:domain) - domain.tech_contacts << same_contact - domain.tech_contacts << same_contact - domain.valid? - domain.errors.full_messages.should match_array(["Tech domain contacts is invalid"]) - end - - it 'should validate uniqueness of tech contacts' do - same_contact = create(:contact, code: 'same_contact') - domain = create(:domain) - domain.admin_contacts << same_contact - domain.admin_contacts << same_contact - domain.valid? - domain.errors.full_messages.should match_array(["Admin domain contacts is invalid"]) - end - - it 'should have whois body by default' do - @domain.whois_record.present?.should == true - end - - it 'should have whois json by default' do - @domain.whois_record.json.present?.should == true - end - - it 'should not be registrant update confirm ready' do - @domain.registrant_update_confirmable?('123').should == false - end - - it 'should expire domains' do - Setting.expire_warning_period = 1 - Setting.redemption_grace_period = 1 - - DomainCron.start_expire_period - @domain.statuses.include?(DomainStatus::EXPIRED).should == false - - old_valid_to = Time.zone.now - 10.days - @domain.valid_to = old_valid_to - @domain.save - - DomainCron.start_expire_period - @domain.reload - @domain.statuses.include?(DomainStatus::EXPIRED).should == true - - DomainCron.start_expire_period - @domain.reload - @domain.statuses.include?(DomainStatus::EXPIRED).should == true - end - - it 'should start redemption grace period' do - old_valid_to = Time.zone.now - 10.days - @domain.valid_to = old_valid_to - @domain.statuses = [DomainStatus::EXPIRED] - @domain.outzone_at, @domain.delete_date = nil, nil - @domain.save - - DomainCron.start_expire_period - @domain.reload - @domain.statuses.include?(DomainStatus::EXPIRED).should == true - end - - context 'with time period settings' do - before :example do - @save_days_to_renew = Setting.days_to_renew_domain_before_expire - @save_warning_period = Setting.expire_warning_period - @save_grace_period = Setting.redemption_grace_period - end - - after :all do - Setting.days_to_renew_domain_before_expire = @save_days_to_renew - Setting.expire_warning_period = @save_warning_period - Setting.redemption_grace_period = @save_grace_period - end - - before :example do - @domain.valid? - end - - context 'with no renewal limit, renew anytime' do - before do - Setting.days_to_renew_domain_before_expire = 0 - end - - it 'should always renew with no policy' do - @domain.renewable?.should be true - end - - it 'should not allow to renew after force delete' do - Setting.redemption_grace_period = 1 - @domain.schedule_force_delete - @domain.renewable?.should be false - end - end - - context 'with renew policy' do - before :example do - @policy = 30 - Setting.days_to_renew_domain_before_expire = @policy - end - - it 'should not allow renew before policy' do - @domain.valid_to = Time.zone.now.beginning_of_day + @policy.days * 2 - @domain.renewable?.should be false - end - - context 'ready to renew' do - before { @domain.valid_to = Time.zone.now + (@policy - 2).days } - - it 'should allow renew' do - @domain.renewable?.should be true - end - - it 'should not allow to renew after force delete' do - Setting.redemption_grace_period = 1 - @domain.schedule_force_delete - @domain.renewable?.should be false - end - end - end - end - - it 'should set pending update' do - @domain.statuses = DomainStatus::OK # restore - @domain.save - @domain.pending_update?.should == false - - @domain.set_pending_update - @domain.pending_update?.should == true - @domain.statuses = DomainStatus::OK # restore - end - - it 'should not set pending update' do - @domain.statuses = DomainStatus::OK # restore - @domain.statuses << DomainStatus::CLIENT_UPDATE_PROHIBITED - @domain.save - - @domain.set_pending_update.should == nil # not updated - @domain.pending_update?.should == false - @domain.statuses = DomainStatus::OK # restore - end - - it 'should set pending delete' do - @domain.nameservers.build(attributes_for(:nameserver)) - @domain.nameservers.build(attributes_for(:nameserver)) - - @domain.statuses = DomainStatus::OK # restore - @domain.save - @domain.pending_delete?.should == false - - @domain.set_pending_delete - @domain.save - @domain.statuses.should == ['pendingDelete', 'serverHold'] - @domain.pending_delete?.should == true - @domain.statuses = ['serverManualInzone'] - @domain.save - @domain.set_pending_delete - @domain.statuses.sort.should == ['pendingDelete', 'serverManualInzone'].sort - @domain.statuses = DomainStatus::OK # restore - end - - it 'should not set pending delele' do - @domain.statuses = DomainStatus::OK # restore - @domain.pending_delete?.should == false - @domain.statuses << DomainStatus::CLIENT_DELETE_PROHIBITED - @domain.save - - @domain.set_pending_delete.should == nil - - @domain.pending_delete?.should == false - @domain.statuses = DomainStatus::OK # restore - end - - it 'should notify registrar' do - text = 'Registrant confirmed domain update: testpollmessage123.ee' - domain = create(:domain, name: 'testpollmessage123.ee') - domain.notify_registrar(:poll_pending_update_confirmed_by_registrant) - domain.registrar.notifications.first.text.should == text - end - - context 'about registrant update confirm' do - before :example do - @domain.registrant_verification_token = 123 - @domain.registrant_verification_asked_at = Time.zone.now - @domain.statuses << DomainStatus::PENDING_UPDATE - end - - it 'should be registrant update confirm ready' do - @domain.registrant_update_confirmable?('123').should == true - end - - it 'should not be registrant update confirm ready when token does not match' do - @domain.registrant_update_confirmable?('wrong-token').should == false - end - - it 'should not be registrant update confirm ready when no correct status' do - @domain.statuses = [] - @domain.registrant_update_confirmable?('123').should == false - end - end - - context 'about registrant update confirm when domain is invalid' do - before :example do - @domain.registrant_verification_token = 123 - @domain.registrant_verification_asked_at = Time.zone.now - @domain.statuses << DomainStatus::PENDING_UPDATE - end - - it 'should be registrant update confirm ready' do - @domain.registrant_update_confirmable?('123').should == true - end - - it 'should not be registrant update confirm ready when token does not match' do - @domain.registrant_update_confirmable?('wrong-token').should == false - end - - it 'should not be registrant update confirm ready when no correct status' do - @domain.statuses = [] - @domain.registrant_update_confirmable?('123').should == false - end - end - end - - it 'validates domain name' do - d = create(:domain) - expect(d.name).to_not be_nil - - invalid = [ - 'a.ee', "#{'a' * 64}.ee", 'ab.eu', 'test.ab.ee', '-test.ee', '-test-.ee', - 'test-.ee', 'te--st.ee', 'õ.pri.ee', 'www.ab.ee', 'test.eu', ' .ee', 'a b.ee', - 'Ž .ee', 'test.edu.ee' - ] - - invalid.each do |x| - expect(build(:domain, name: x).valid?).to be false - end - - valid = [ - 'ab.ee', "#{'a' * 63}.ee", 'te-s-t.ee', 'jäääär.ee', 'päike.pri.ee', - 'õigus.com.ee', 'õäöü.fie.ee', 'test.med.ee', 'žä.ee', ' ŽŠ.ee ' - ] - - valid.each do |x| - expect(build(:domain, name: x).valid?).to be true - end - - invalid_punycode = ['xn--geaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-4we.pri.ee'] - - invalid_punycode.each do |x| - expect(build(:domain, name: x).valid?).to be false - end - - valid_punycode = ['xn--ge-uia.pri.ee', 'xn--geaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-9te.pri.ee'] - - valid_punycode.each do |x| - expect(build(:domain, name: x).valid?).to be true - end - end - - it 'should not create zone origin domain' do - d = build(:domain, name: 'ee') - d.save.should == false - expect(d.errors.full_messages).to include('Data management policy violation: Domain name is blocked [name]') - - d = build(:domain, name: 'bla') - d.save.should == false - expect(d.errors.full_messages).to include('Domain name Domain name is invalid') - end - - it 'downcases domain' do - d = Domain.new(name: 'TesT.Ee') - expect(d.name).to eq('test.ee') - expect(d.name_puny).to eq('test.ee') - expect(d.name_dirty).to eq('test.ee') - end - - it 'should be valid when name length is exatly 63 in characters' do - d = create(:domain, name: "#{'a' * 63}.ee") - d.valid? - d.errors.full_messages.should == [] - end - - it 'should not be valid when name length is longer than 63 characters' do - d = build(:domain, name: "#{'a' * 64}.ee") - d.valid? - d.errors.full_messages.should match_array([ - "Domain name Domain name is invalid", - "Puny label Domain name is too long (maximum is 63 characters)" - ]) - end - - it 'should not be valid when name length is longer than 63 characters' do - d = build(:domain, - name: "xn--4caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.ee") - d.valid? - d.errors.full_messages.should match_array([ - "Domain name Domain name is invalid", - "Puny label Domain name is too long (maximum is 63 characters)" - ]) - end - - it 'should be valid when name length is 63 characters' do - d = build(:domain, - name: "õäöüšžõäöüšžõäöüšžõäöüšžõäöüšžõäöüšžõäöüšžab123.pri.ee") - d.valid? - d.errors.full_messages.should match_array([ - ]) - end - - it 'should not be valid when name length is longer than 63 punycode characters' do - d = build(:domain, name: "#{'ä' * 63}.ee") - d.valid? - d.errors.full_messages.should == [ - "Puny label Domain name is too long (maximum is 63 characters)" - ] - end - - it 'should not be valid when name length is longer than 63 punycode characters' do - d = build(:domain, name: "#{'ä' * 64}.ee") - d.valid? - d.errors.full_messages.should match_array([ - "Domain name Domain name is invalid", - "Puny label Domain name is too long (maximum is 63 characters)" - ]) - end - - it 'should not be valid when name length is longer than 63 punycode characters' do - d = build(:domain, name: "#{'ä' * 63}.pri.ee") - d.valid? - d.errors.full_messages.should match_array([ - "Puny label Domain name is too long (maximum is 63 characters)" - ]) - end - - it 'should be valid when punycode name length is not longer than 63' do - d = build(:domain, name: "#{'ä' * 53}.pri.ee") - d.valid? - d.errors.full_messages.should == [] - end - - it 'should be valid when punycode name length is not longer than 63' do - d = build(:domain, name: "#{'ä' * 57}.ee") - d.valid? - d.errors.full_messages.should == [] - end - - it 'should not be valid when name length is one pynicode' do - d = build(:domain, name: "xn--4ca.ee") - d.valid? - d.errors.full_messages.should == ["Domain name Domain name is invalid"] - end - - it 'should not be valid with at character' do - d = build(:domain, name: 'dass@sf.ee') - d.valid? - d.errors.full_messages.should == ["Domain name Domain name is invalid"] - end - - it 'should not be valid with invalid characters' do - d = build(:domain, name: '@ba)s(?ä_:-df.ee') - d.valid? - d.errors.full_messages.should == ["Domain name Domain name is invalid"] - end - - it 'should be valid when name length is two pynicodes' do - d = build(:domain, name: "xn--4caa.ee") - d.valid? - d.errors.full_messages.should == [] - end - - it 'should be valid when name length is two pynicodes' do - d = build(:domain, name: "xn--4ca0b.ee") - d.valid? - d.errors.full_messages.should == [] - end - - it 'does not create a reserved domain' do - create(:reserved_domain, name: 'test.ee') - - domain = build(:domain, name: 'test.ee') - domain.validate - - expect(domain.errors[:base]).to include('Required parameter missing; reserved>pw element required for reserved domains') - end - - it 'manages statuses automatically' do - d = build(:domain) - - d.nameservers.build(attributes_for(:nameserver)) - d.nameservers.build(attributes_for(:nameserver)) - - d.save! - - expect(d.statuses.count).to eq(1) - expect(d.statuses.first).to eq(DomainStatus::OK) - - d.period = 2 - d.save - - d.reload - expect(d.statuses.count).to eq(1) - expect(d.statuses.first).to eq(DomainStatus::OK) - - d.statuses << DomainStatus::CLIENT_DELETE_PROHIBITED - d.save - - d.reload - - expect(d.statuses.count).to eq(1) - expect(d.statuses.first).to eq(DomainStatus::CLIENT_DELETE_PROHIBITED) - end -end - -RSpec.describe Domain do - it { is_expected.to alias_attribute(:on_hold_time, :outzone_at) } - it { is_expected.to alias_attribute(:outzone_time, :outzone_at) } - - describe 'registrar validation', db: false do - let(:domain) { described_class.new } - - it 'rejects absent' do - domain.registrar = nil - domain.validate - expect(domain.errors).to have_key(:registrar) - end - end - - describe 'registrant validation', db: false do - let(:domain) { described_class.new } - - it 'rejects absent' do - domain.registrant = nil - domain.validate - expect(domain.errors).to have_key(:registrant) - end - end - - describe 'period validation', db: false do - let(:domain) { described_class.new } - - it 'rejects absent' do - domain.period = nil - domain.validate - expect(domain.errors).to have_key(:period) - end - - it 'rejects fractional' do - domain.period = 1.1 - domain.validate - expect(domain.errors).to have_key(:period) - end - - it 'accepts integer' do - domain.period = 1 - domain.validate - expect(domain.errors).to_not have_key(:period) - end - end - - describe 'admin contact count validation' do - let(:domain) { described_class.new } - - before :example do - Setting.admin_contacts_min_count = 1 - Setting.admin_contacts_max_count = 2 - end - - it 'rejects less than min' do - domain.validate - expect(domain.errors).to have_key(:admin_domain_contacts) - end - - it 'rejects more than max' do - (Setting.admin_contacts_max_count + 1).times { domain.admin_domain_contacts << build(:admin_domain_contact) } - domain.validate - expect(domain.errors).to have_key(:admin_domain_contacts) - end - - it 'accepts min' do - Setting.admin_contacts_min_count.times { domain.admin_domain_contacts << build(:admin_domain_contact) } - domain.validate - expect(domain.errors).to_not have_key(:admin_domain_contacts) - end - - it 'accepts max' do - Setting.admin_contacts_max_count.times { domain.admin_domain_contacts << build(:admin_domain_contact) } - domain.validate - expect(domain.errors).to_not have_key(:admin_domain_contacts) - end - end - - describe 'nameserver validation', db: true do - let(:domain) { described_class.new(name: 'whatever.test') } - - it 'rejects less than min' do - Setting.ns_min_count = 2 - domain.nameservers.build(attributes_for(:nameserver)) - domain.validate - expect(domain.errors).to have_key(:nameservers) - end - - it 'rejects more than max' do - Setting.ns_min_count = 1 - Setting.ns_max_count = 1 - domain.nameservers.build(attributes_for(:nameserver)) - domain.nameservers.build(attributes_for(:nameserver)) - domain.validate - expect(domain.errors).to have_key(:nameservers) - end - - it 'accepts min' do - Setting.ns_min_count = 1 - domain.nameservers.build(attributes_for(:nameserver)) - domain.validate - expect(domain.errors).to_not have_key(:nameservers) - end - - it 'accepts max' do - Setting.ns_min_count = 1 - Setting.ns_max_count = 2 - domain.nameservers.build(attributes_for(:nameserver)) - domain.nameservers.build(attributes_for(:nameserver)) - domain.validate - expect(domain.errors).to_not have_key(:nameservers) - end - - context 'when nameserver is optional' do - before :example do - allow(Domain).to receive(:nameserver_required?).and_return(false) - end - - it 'rejects less than min' do - Setting.ns_min_count = 2 - domain.nameservers.build(attributes_for(:nameserver)) - domain.validate - expect(domain.errors).to have_key(:nameservers) - end - - it 'accepts absent' do - domain.validate - expect(domain.errors).to_not have_key(:nameservers) - end - end - - context 'when nameserver is required' do - before :example do - allow(Domain).to receive(:nameserver_required?).and_return(true) - end - - it 'rejects absent' do - domain.validate - expect(domain.errors).to have_key(:nameservers) - end - end - end - - describe '::nameserver_required?' do - before do - Setting.nameserver_required = 'test' - end - - it 'returns setting value' do - expect(described_class.nameserver_required?).to eq('test') - end - end - - describe '::expire_warning_period', db: true do - before :example do - Setting.expire_warning_period = 1 - end - - it 'returns expire warning period' do - expect(described_class.expire_warning_period).to eq(1.day) - end - end - - describe '::redemption_grace_period', db: true do - before :example do - Setting.redemption_grace_period = 1 - end - - it 'returns redemption grace period' do - expect(described_class.redemption_grace_period).to eq(1.day) - end - end - - describe '#set_server_hold' do - let(:domain) { described_class.new } - - before :example do - travel_to Time.zone.parse('05.07.2010') - domain.set_server_hold - end - - it 'sets corresponding status' do - expect(domain.statuses).to include(DomainStatus::SERVER_HOLD) - end - - it 'sets :outzone_at to now' do - expect(domain.outzone_at).to eq(Time.zone.parse('05.07.2010')) - end - end - - describe '#set_graceful_expired' do - let(:domain) { described_class.new } - - before :example do - expect(described_class).to receive(:expire_warning_period).and_return(1.day) - expect(described_class).to receive(:redemption_grace_period).and_return(2.days) - expect(domain).to receive(:valid_to).and_return(Time.zone.parse('05.07.2010 10:30')) - - domain.set_graceful_expired - end - - it 'sets :outzone_at to :valid_to + expire warning period' do - expect(domain.outzone_at).to eq(Time.zone.parse('06.07.2010 10:30')) - end - - it 'sets :delete_date to :outzone_at + redemption grace period' do - expect(domain.delete_date).to eq(Date.parse('08.07.2010')) - end - end - - describe '::outzone_candidates', db: true do - before :example do - travel_to Time.zone.parse('05.07.2010 00:00') - - create(:zone, origin: 'ee') - - create(:domain, id: 1, outzone_time: Time.zone.parse('04.07.2010 23:59')) - create(:domain, id: 2, outzone_time: Time.zone.parse('05.07.2010 00:00')) - create(:domain, id: 3, outzone_time: Time.zone.parse('05.07.2010 00:01')) - end - - it 'returns domains with outzone time in the past' do - expect(described_class.outzone_candidates.ids).to eq([1]) - end - end - - describe '::uses_zone?', db: true do - let!(:zone) { create(:zone, origin: 'domain.tld') } - - context 'when zone is used' do - let!(:domain) { create(:domain, name: 'test.domain.tld') } - specify { expect(described_class.uses_zone?(zone)).to be true } - end - - context 'when zone is unused' do - specify { expect(described_class.uses_zone?(zone)).to be false } - end - end - - describe '#new_registrant_email' do - let(:domain) { described_class.new(pending_json: { new_registrant_email: 'test@test.com' }) } - - it 'returns new registrant\'s email' do - expect(domain.new_registrant_email).to eq('test@test.com') - end - end - - describe '#new_registrant_id' do - let(:domain) { described_class.new(pending_json: { new_registrant_id: 1 }) } - - it 'returns new registrant\'s id' do - expect(domain.new_registrant_id).to eq(1) - end - end -end diff --git a/spec/models/epp/domain_spec.rb b/spec/models/epp/domain_spec.rb deleted file mode 100644 index 402305527..000000000 --- a/spec/models/epp/domain_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ -require 'rails_helper' - -RSpec.describe Epp::Domain, db: false do - describe '::new_from_epp' do - let(:domain_blueprint) { described_class.new } - subject(:domain) { described_class.new_from_epp(nil, nil) } - - before :example do - travel_to Time.zone.parse('05.07.2010') - - domain_blueprint.period = 1 - domain_blueprint.period_unit = 'y' - - expect(described_class).to receive(:new).and_return(domain_blueprint) - expect(domain_blueprint).to receive(:attrs_from).and_return({}) - expect(domain_blueprint).to receive(:attach_default_contacts) - end - - describe 'domain' do - it 'has :registered_at set to now' do - expect(domain.registered_at).to eq(Time.zone.parse('05.07.2010')) - end - - it 'has :valid_to set to the beginning of next day after :registered_at' do - expect(domain.valid_to).to eq(Time.zone.parse('06.07.2011 00:00')) - end - end - end -end diff --git a/spec/models/epp/response/result_spec.rb b/spec/models/epp/response/result_spec.rb deleted file mode 100644 index 606a4c2de..000000000 --- a/spec/models/epp/response/result_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -require 'rails_helper' - -RSpec.describe EPP::Response::Result, db: false do - # https://tools.ietf.org/html/rfc5730#section-3 - describe '::codes' do - it 'returns codes' do - codes = { - '1000' => :success, - '1001' => :success_pending, - '1300' => :success_empty_queue, - '1301' => :success_dequeue, - '2001' => :syntax_error, - '2003' => :required_param_missing, - '2005' => :param_syntax_error, - '2308' => :data_management_policy_violation - } - - expect(described_class.codes).to eq(codes) - end - end -end diff --git a/spec/models/epp_contact_spec.rb b/spec/models/epp_contact_spec.rb deleted file mode 100644 index 401a63cc6..000000000 --- a/spec/models/epp_contact_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -require 'rails_helper' - -describe Epp::Contact, '.check_availability' do - before do - create(:contact, code: 'asd12') - create(:contact, code: 'asd13') - end - - it 'should return array if argument is string' do - response = Epp::Contact.check_availability('asd12') - response.class.should == Array - response.length.should == 1 - end - - it 'should return in_use and available codes' do - code = Contact.first.code - code_ = Contact.last.code - - response = Epp::Contact.check_availability([code, code_, 'asd14']) - response.class.should == Array - response.length.should == 3 - - response[0][:avail].should == 0 - response[0][:code].should == code - - response[1][:avail].should == 0 - response[1][:code].should == code_ - - response[2][:avail].should == 1 - response[2][:code].should == 'asd14' - end -end diff --git a/spec/models/keyrelay_spec.rb b/spec/models/keyrelay_spec.rb deleted file mode 100644 index fc388dfed..000000000 --- a/spec/models/keyrelay_spec.rb +++ /dev/null @@ -1,77 +0,0 @@ -require 'rails_helper' - -describe Keyrelay do - before :example do - Setting.ds_algorithm = 2 - Setting.ds_data_allowed = true - Setting.ds_data_with_key_allowed = true - Setting.key_data_allowed = true - - Setting.dnskeys_min_count = 0 - Setting.dnskeys_max_count = 9 - Setting.ns_min_count = 2 - Setting.ns_max_count = 11 - - Setting.transfer_wait_time = 0 - - Setting.admin_contacts_min_count = 1 - Setting.admin_contacts_max_count = 10 - Setting.tech_contacts_min_count = 0 - Setting.tech_contacts_max_count = 10 - - Setting.client_side_status_editing_enabled = true - - create(:zone, origin: 'ee') - end - - context 'with invalid attribute' do - before :example do - @keyrelay = Keyrelay.new - end - - it 'should not be valid' do - @keyrelay.valid? - @keyrelay.errors.full_messages.should match_array([ - "Auth info pw Password is missing", - "Domain is missing", - "Key data alg Algorithm is missing", - "Key data flags Flag is missing", - "Key data protocol Protocol is missing", - "Key data public key Public key is missing", - "Only one parameter allowed: relative or absolute" - ]) - end - end - - context 'with valid attributes' do - before :example do - @keyrelay = create(:keyrelay) - end - - it 'should be valid' do - @keyrelay.valid? - @keyrelay.errors.full_messages.should match_array([]) - end - - it 'should be valid twice' do - @keyrelay = create(:keyrelay) - @keyrelay.valid? - @keyrelay.errors.full_messages.should match_array([]) - end - - it 'is in pending status' do - @keyrelay.status.should == 'pending' - end - end - - it 'is in expired status' do - kr = create(:keyrelay, pa_date: Time.zone.now - 2.weeks) - expect(kr.status).to eq('expired') - end - - it 'does not accept invalid relative expiry' do - kr = build(:keyrelay, expiry_relative: 'adf') - expect(kr.save).to eq(false) - expect(kr.errors[:expiry_relative].first).to eq('Expiry relative must be compatible to ISO 8601') - end -end diff --git a/spec/models/legal_document_spec.rb b/spec/models/legal_document_spec.rb deleted file mode 100644 index 03c83bc89..000000000 --- a/spec/models/legal_document_spec.rb +++ /dev/null @@ -1,68 +0,0 @@ -require 'rails_helper' - -describe LegalDocument do - context 'tasks' do - it 'make files uniq' do - create(:zone, origin: 'ee') - create(:zone, origin: 'pri.ee') - create(:zone, origin: 'med.ee') - create(:zone, origin: 'fie.ee') - create(:zone, origin: 'com.ee') - LegalDocument.explicitly_write_file = true - PaperTrail.enabled = true - - domain = create(:domain) - domain2 = create(:domain) - legals = [] - legals << original = domain.legal_documents.create!(body: Base64.encode64('S' * 4.kilobytes)) - legals << copy = domain.legal_documents.create!(body: Base64.encode64('S' * 4.kilobytes)) - legals << skipping_as_different_domain = domain2.legal_documents.create!(body: Base64.encode64('S' * 4.kilobytes)) - legals << skipping_as_different = domain.legal_documents.create!(body: Base64.encode64('D' * 4.kilobytes)) - legals << skipping_as_no_checksum = domain.legal_documents.create!(checksum: nil, body: Base64.encode64('S' * 4.kilobytes)) - legals << skipping_as_no_checksum2 = domain.legal_documents.create!(checksum: "", body: Base64.encode64('S' * 4.kilobytes)) - legals << registrant_copy = domain.registrant.legal_documents.create!(body: Base64.encode64('S' * 4.kilobytes)) - legals << registrant_skipping_as_different = domain.registrant.legal_documents.create!(body: Base64.encode64('Q' * 4.kilobytes)) - legals << tech_copy = domain.tech_contacts.first.legal_documents.create!(body: Base64.encode64('S' * 4.kilobytes)) - legals << tech_skipping_as_different = domain.tech_contacts.first.legal_documents.create!(body: Base64.encode64('W' * 4.kilobytes)) - legals << admin_copy = domain.admin_contacts.first.legal_documents.create!(body: Base64.encode64('S' * 4.kilobytes)) - legals << admin_skipping_as_different = domain.admin_contacts.first.legal_documents.create!(body: Base64.encode64('E' * 4.kilobytes)) - legals << new_second_tech_contact = domain2.tech_contacts.first.legal_documents.create!(body: Base64.encode64('S' * 4.kilobytes)) - domain.tech_contacts << domain2.tech_contacts.first - - - # writing nesting to history - domain.update(updated_at: Time.now) - domain2.update(updated_at: Time.now) - domain.reload - - skipping_as_no_checksum.update_columns(checksum: nil) - skipping_as_no_checksum2.update_columns(checksum: "") - skipping_as_no_checksum.reload - skipping_as_no_checksum2.reload - skipping_as_no_checksum.path.should_not == skipping_as_no_checksum2.path - - skipping_as_no_checksum.checksum.should == nil - skipping_as_no_checksum2.checksum.should == "" - original.checksum.should == copy.checksum - original.checksum.should_not == skipping_as_different.checksum - domain.tech_contacts.count.should == 2 - - LegalDocument.remove_duplicates - LegalDocument.remove_duplicates - LegalDocument.remove_duplicates - legals.each(&:reload) - - skipping_as_no_checksum.path.should_not be(skipping_as_no_checksum2.path) - original.path.should_not == skipping_as_different.path - original.path.should_not == skipping_as_different_domain.path - original.path.should_not == registrant_skipping_as_different.path - original.path.should_not == tech_skipping_as_different.path - original.path.should_not == admin_skipping_as_different.path - original.path.should == copy.path - original.path.should == registrant_copy.path - - skipping_as_different_domain.path.should_not == new_second_tech_contact.path - end - end - -end diff --git a/spec/models/registrant_verification_spec.rb b/spec/models/registrant_verification_spec.rb deleted file mode 100644 index 6438fda84..000000000 --- a/spec/models/registrant_verification_spec.rb +++ /dev/null @@ -1,59 +0,0 @@ -require 'rails_helper' - -describe RegistrantVerification do - before :example do - Setting.ds_algorithm = 2 - Setting.ds_data_allowed = true - Setting.ds_data_with_key_allowed = true - Setting.key_data_allowed = true - - Setting.dnskeys_min_count = 0 - Setting.dnskeys_max_count = 9 - Setting.ns_min_count = 2 - Setting.ns_max_count = 11 - - Setting.transfer_wait_time = 0 - - Setting.admin_contacts_min_count = 1 - Setting.admin_contacts_max_count = 10 - Setting.tech_contacts_min_count = 0 - Setting.tech_contacts_max_count = 10 - - Setting.client_side_status_editing_enabled = true - - create(:zone, origin: 'ee') - end - context 'with invalid attribute' do - before :example do - @registrant_verification = RegistrantVerification.new - end - - it 'should not be valid' do - @registrant_verification.valid? - @registrant_verification.errors.full_messages.should match_array([ - "Domain name is missing", - "Verification token is missing", - "Action is missing", - "Action type is missing", - "Domain is missing" - ]) - end - end - - context 'with valid attributes' do - before :example do - @registrant_verification = create(:registrant_verification) - end - - it 'should be valid' do - @registrant_verification.valid? - @registrant_verification.errors.full_messages.should match_array([]) - end - - it 'should be valid twice' do - @registrant_verification = create(:registrant_verification) - @registrant_verification.valid? - @registrant_verification.errors.full_messages.should match_array([]) - end - end -end diff --git a/spec/models/setting_spec.rb b/spec/models/setting_spec.rb deleted file mode 100644 index fd392c6d2..000000000 --- a/spec/models/setting_spec.rb +++ /dev/null @@ -1,60 +0,0 @@ -require 'rails_helper' - -RSpec.describe Setting do - describe 'integer_settings', db: false do - it 'returns integer settings' do - settings = %i[ - admin_contacts_min_count - admin_contacts_max_count - tech_contacts_min_count - tech_contacts_max_count - orphans_contacts_in_months - ds_digest_type - dnskeys_min_count - dnskeys_max_count - ns_min_count - ns_max_count - transfer_wait_time - invoice_number_min - invoice_number_max - days_to_keep_invoices_active - days_to_keep_overdue_invoices_active - days_to_renew_domain_before_expire - expire_warning_period - redemption_grace_period - expire_pending_confirmation - ] - - expect(described_class.integer_settings).to eq(settings) - end - end - - describe 'float_settings', db: false do - it 'returns float settings' do - settings = %i[ - registry_vat_prc - minimum_deposit - ] - - expect(described_class.float_settings).to eq(settings) - end - end - - describe 'boolean_settings', db: false do - it 'returns boolean settings' do - settings = %i[ - ds_data_allowed - key_data_allowed - client_side_status_editing_enabled - registrar_ip_whitelist_enabled - api_ip_whitelist_enabled - request_confrimation_on_registrant_change_enabled - request_confirmation_on_domain_deletion_enabled - nameserver_required - address_processing - ] - - expect(described_class.boolean_settings).to eq(settings) - end - end -end diff --git a/spec/models/white_ip_spec.rb b/spec/models/white_ip_spec.rb deleted file mode 100644 index fa28991f1..000000000 --- a/spec/models/white_ip_spec.rb +++ /dev/null @@ -1,53 +0,0 @@ -require 'rails_helper' - -describe WhiteIp do - context 'with invalid attribute' do - before :all do - @white_ip = WhiteIp.new - end - - it 'is not valid' do - @white_ip.valid? - @white_ip.errors.full_messages.should match_array([ - 'IPv4 or IPv6 must be present' - ]) - end - - it 'returns an error with invalid ips' do - @white_ip.ipv4 = 'bla' - @white_ip.ipv6 = 'bla' - - @white_ip.valid? - @white_ip.errors[:ipv4].should == ['is invalid'] - @white_ip.errors[:ipv6].should == ['is invalid'] - end - end - - describe '#include_ip?' do - context 'when given ip v4 exists' do - before do - create(:white_ip, ipv4: '127.0.0.1') - end - - specify do - expect(described_class.include_ip?('127.0.0.1')).to be true - end - end - - context 'when given ip v6 exists' do - before do - create(:white_ip, ipv6: '::1') - end - - specify do - expect(described_class.include_ip?('::1')).to be true - end - end - - context 'when given ip does not exists', db: false do - specify do - expect(described_class.include_ip?('127.0.0.1')).to be false - end - end - end -end diff --git a/spec/presenters/domain_presenter_spec.rb b/spec/presenters/domain_presenter_spec.rb deleted file mode 100644 index 2a1b1bc45..000000000 --- a/spec/presenters/domain_presenter_spec.rb +++ /dev/null @@ -1,98 +0,0 @@ -require 'rails_helper' - -RSpec.describe DomainPresenter do - let(:presenter) { described_class.new(domain: domain, view: view) } - - describe '#expire_time' do - let(:domain) { instance_double(Domain, expire_time: Time.zone.parse('05.07.2010')) } - - it 'returns localized time' do - expect(view).to receive(:l).with(Time.zone.parse('05.07.2010')).and_return('expire time') - expect(presenter.expire_time).to eq('expire time') - end - end - - describe '#expire_date' do - let(:domain) { instance_double(Domain, expire_time: Time.zone.parse('05.07.2010')) } - - it 'returns localized date' do - expect(view).to receive(:l).with(Time.zone.parse('05.07.2010'), format: :date).and_return('expire date') - expect(presenter.expire_date).to eq('expire date') - end - end - - describe '#on_hold_date' do - subject(:on_hold_date) { presenter.on_hold_date } - - context 'when present' do - let(:domain) { instance_double(Domain, on_hold_time: '05.07.2010') } - - it 'returns localized date' do - expect(view).to receive(:l).with('05.07.2010', format: :date).and_return('on hold date') - expect(on_hold_date).to eq('on hold date') - end - end - - context 'when absent' do - let(:domain) { instance_double(Domain, on_hold_time: nil) } - - specify { expect(on_hold_date).to be_nil } - end - end - - describe '#delete_date' do - subject(:delete_date) { presenter.delete_date } - - context 'when present' do - let(:domain) { instance_double(Domain, delete_date: '05.07.2010') } - - it 'returns localized date' do - expect(view).to receive(:l).with('05.07.2010').and_return('delete date') - expect(delete_date).to eq('delete date') - end - end - - context 'when absent' do - let(:domain) { instance_double(Domain, delete_date: nil) } - - specify { expect(delete_date).to be_nil } - end - end - - describe '#force_delete_date' do - subject(:force_delete_date) { presenter.force_delete_date } - - context 'when present' do - let(:domain) { instance_double(Domain, force_delete_date: '05.07.2010', force_delete_scheduled?: true) } - - it 'returns localized date' do - expect(view).to receive(:l).with('05.07.2010').and_return('delete date') - expect(force_delete_date).to eq('delete date') - end - end - - context 'when absent' do - let(:domain) { instance_double(Domain, force_delete_date: nil, force_delete_scheduled?: false) } - - specify { expect(force_delete_date).to be_nil } - end - end - - domain_delegatable_attributes = %i( - name - transfer_code - registrant - registrant_id - ) - - domain_delegatable_attributes.each do |attribute_name| - describe "##{attribute_name}" do - let(:domain) { instance_spy(Domain) } - - it 'delegates to domain' do - presenter.send(attribute_name) - expect(domain).to have_received(attribute_name) - end - end - end -end diff --git a/spec/presenters/registrant_presenter_spec.rb b/spec/presenters/registrant_presenter_spec.rb deleted file mode 100644 index 224a0504f..000000000 --- a/spec/presenters/registrant_presenter_spec.rb +++ /dev/null @@ -1,81 +0,0 @@ -require 'rails_helper' - -RSpec.describe RegistrantPresenter do - let(:registrant) { instance_double(Registrant) } - let(:presenter) { described_class.new(registrant: registrant, view: view) } - - describe '#country' do - let(:country) { instance_double(Country) } - - before :example do - allow(registrant).to receive(:country).and_return(country) - end - - it 'returns country name in current locale by default' do - expect(country).to receive(:translation).with(I18n.locale).and_return('test country') - expect(presenter.country).to eq('test country') - end - - it 'returns country name in given locale' do - expect(country).to receive(:translation).with(:de).and_return('test country') - expect(presenter.country(locale: :de)).to eq('test country') - end - end - - describe '#ident_country' do - let(:ident_country) { instance_double(Country) } - - before :example do - allow(registrant).to receive(:ident_country).and_return(ident_country) - end - - it 'returns country name in current locale by default' do - expect(ident_country).to receive(:translation).with(I18n.locale).and_return('test country') - expect(presenter.ident_country).to eq('test country') - end - - it 'returns country name in given locale' do - expect(ident_country).to receive(:translation).with(:de).and_return('test country') - expect(presenter.ident_country(locale: :de)).to eq('test country') - end - end - - describe '#domain_names_with_roles' do - before :example do - roles = %i[registrant admin_domain_contact tech_domain_contact] - allow(registrant).to receive(:domain_names_with_roles) - .and_return({ 'test.com' => roles, - 'test.org' => %i[registrant] }) - end - - it 'returns domain names with unique roles in current locale by default' do - text = "test.com (Registrant, Administrative contact, Technical contact)" \ - "\ntest.org (Registrant)" - expect(presenter.domain_names_with_roles).to eq(text) - end - end - - registrant_delegatable_attributes = %i( - name - ident - phone - email - priv? - street - city - state - zip - id_code - reg_no - linked? - ) - - registrant_delegatable_attributes.each do |attr_name| - describe "##{attr_name}" do - it 'delegates to registrant' do - expect(registrant).to receive(attr_name).and_return('test') - expect(presenter.send(attr_name)).to eq('test') - end - end - end -end diff --git a/spec/presenters/registrar_presenter_spec.rb b/spec/presenters/registrar_presenter_spec.rb deleted file mode 100644 index 8c0196c51..000000000 --- a/spec/presenters/registrar_presenter_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'rails_helper' - -RSpec.describe RegistrarPresenter do - let(:registrar) { instance_double(Registrar) } - let(:presenter) { described_class.new(registrar: registrar, view: view) } - - describe '#name' do - it 'returns name' do - expect(registrar).to receive(:name).and_return('test name') - expect(presenter.name).to eq('test name') - end - end - - describe '#email' do - it 'returns email' do - expect(registrar).to receive(:email).and_return('test email') - expect(presenter.email).to eq('test email') - end - end - - describe '#phone' do - it 'returns phone' do - expect(registrar).to receive(:phone).and_return('test phone') - expect(presenter.phone).to eq('test phone') - end - end - - describe '#website' do - it 'returns website' do - expect(registrar).to receive(:website).and_return('test') - expect(presenter.website).to eq('test') - end - end -end diff --git a/spec/presenters/user_presenter_spec.rb b/spec/presenters/user_presenter_spec.rb deleted file mode 100644 index ba9e1673f..000000000 --- a/spec/presenters/user_presenter_spec.rb +++ /dev/null @@ -1,16 +0,0 @@ -require 'rails_helper' - -RSpec.describe UserPresenter do - let(:presenter) { described_class.new(user: user, view: view) } - - describe '#login_with_role' do - let(:user) { instance_double(ApiUser, - login: 'login', - roles: %w[role], - registrar_name: 'registrar') } - - it 'returns username with role and registrar' do - expect(presenter.login_with_role).to eq('login (role) - registrar') - end - end -end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb deleted file mode 100644 index aead0dfa5..000000000 --- a/spec/rails_helper.rb +++ /dev/null @@ -1,67 +0,0 @@ -ENV['RAILS_ENV'] ||= 'test' -require 'spec_helper' -require File.expand_path('../../config/environment', __FILE__) -require 'rspec/rails' -require 'paper_trail/frameworks/rspec' -require 'money-rails/test_helpers' -require 'support/requests/session_helpers' -require 'support/requests/epp_helpers' -require 'support/features/session_helpers' -require 'support/matchers/alias_attribute' -require 'support/matchers/epp/code' -require 'support/matchers/epp/have_result' - -require 'support/capybara' -require 'support/devise' -require 'support/factory_bot' -require 'support/database_cleaner' -require 'support/paper_trail' -require 'support/settings' - -ActiveRecord::Migration.maintain_test_schema! -Setting.registry_country_code = 'US' - -RSpec.configure do |config| - config.include ActionView::TestCase::Behavior, type: :presenter - config.include ActiveSupport::Testing::TimeHelpers - config.include Requests::SessionHelpers, type: :request - config.include Features::SessionHelpers, type: :feature - config.include AbstractController::Translation, type: :request - config.include AbstractController::Translation, type: :feature - config.include AbstractController::Translation, type: :mailer - config.include Requests::EPPHelpers, epp: true - config.include Matchers::EPP, epp: true - config.include Devise::Test::IntegrationHelpers, type: :feature - config.include Devise::Test::IntegrationHelpers, type: :request - - config.define_derived_metadata(file_path: %r[/spec/features/]) do |metadata| - metadata[:db] = true if metadata[:db].nil? - end - - config.define_derived_metadata(file_path: %r[/spec/models/]) do |metadata| - metadata[:db] = true if metadata[:db].nil? - end - - config.define_derived_metadata(file_path: %r[/spec/presenters/]) do |metadata| - metadata[:type] = :presenter - end - - config.define_derived_metadata(file_path: %r[/spec/requests/]) do |metadata| - metadata[:db] = true if metadata[:db].nil? - end - - config.define_derived_metadata(file_path: %r[/spec/requests/epp/]) do |metadata| - metadata[:epp] = true if metadata[:epp].nil? - end - - config.define_derived_metadata(file_path: %r[/spec/api/]) do |metadata| - metadata[:type] = :request - end - - config.use_transactional_fixtures = false - config.infer_spec_type_from_file_location! - - config.expect_with :rspec do |c| - c.syntax = [:should, :expect] - end -end diff --git a/spec/requests/admin/billing/prices/create_spec.rb b/spec/requests/admin/billing/prices/create_spec.rb deleted file mode 100644 index 14fe63c08..000000000 --- a/spec/requests/admin/billing/prices/create_spec.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'admin price create', settings: false do - let!(:zone) { create(:zone, id: 1, origin: 'test') } - subject(:price) { Billing::Price.first } - - before :example do - sign_in_to_admin_area - end - - it 'creates new price' do - expect { post admin_prices_path, price: attributes_for(:price, zone_id: '1') } - .to change { Billing::Price.count }.from(0).to(1) - end - - it 'saves zone' do - post admin_prices_path, price: attributes_for(:price, zone_id: '1') - expect(price.zone_id).to eq(1) - end - - it 'saves operation category' do - post admin_prices_path, price: - attributes_for(:price, zone_id: '1', operation_category: Billing::Price.operation_categories.first) - expect(price.operation_category).to eq(Billing::Price.operation_categories.first) - end - - it 'saves duration in months' do - post admin_prices_path, price: attributes_for(:price, zone_id: '1', duration: '3 mons') - expect(price.duration).to eq('3 mons') - end - - it 'saves duration in years' do - post admin_prices_path, price: attributes_for(:price, zone_id: '1', duration: '1 year') - expect(price.duration).to eq('1 year') - end - - it 'saves valid_from' do - post admin_prices_path, price: attributes_for(:price, zone_id: '1', valid_from: '2010-07-06') - expect(price.valid_from).to eq(Time.zone.parse('06.07.2010')) - end - - it 'saves valid_to' do - post admin_prices_path, price: attributes_for(:price, zone_id: '1', valid_to: '2010-07-06') - expect(price.valid_to).to eq(Time.zone.parse('06.07.2010')) - end - - it 'redirects to :index' do - post admin_prices_path, price: attributes_for(:price, zone_id: '1') - expect(response).to redirect_to admin_prices_url - end -end diff --git a/spec/requests/admin/billing/prices/expire_spec.rb b/spec/requests/admin/billing/prices/expire_spec.rb deleted file mode 100644 index 79612bbc9..000000000 --- a/spec/requests/admin/billing/prices/expire_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'admin price expire', settings: false do - before :example do - sign_in_to_admin_area - end - - it 'expires price' do - price = create(:effective_price) - - expect { patch expire_admin_price_path(price); price.reload } - .to change { price.expired? }.from(false).to(true) - end - - it 'redirects to :index' do - price = create(:effective_price) - - patch expire_admin_price_path(price) - - expect(response).to redirect_to admin_prices_url - end -end diff --git a/spec/requests/admin/billing/prices/update_spec.rb b/spec/requests/admin/billing/prices/update_spec.rb deleted file mode 100644 index 0b8abcb83..000000000 --- a/spec/requests/admin/billing/prices/update_spec.rb +++ /dev/null @@ -1,71 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'admin price update', settings: false do - before :example do - sign_in_to_admin_area - end - - it 'updates zone' do - price = create(:price) - create(:zone, id: 2) - - patch admin_price_path(price), price: attributes_for(:price, zone_id: '2') - price.reload - - expect(price.zone_id).to eq(2) - end - - it 'updates operation category' do - price = create(:price, operation_category: Billing::Price.operation_categories.first) - - patch admin_price_path(price), - price: attributes_for(:price, operation_category: Billing::Price.operation_categories.second) - price.reload - - expect(price.operation_category).to eq(Billing::Price.operation_categories.second) - end - - it 'updates duration in months' do - price = create(:price, duration: '3 mons') - - patch admin_price_path(price), price: attributes_for(:price, duration: '6 mons') - price.reload - - expect(price.duration).to eq('6 mons') - end - - it 'updates duration in years' do - price = create(:price, duration: '1 year') - - patch admin_price_path(price), price: attributes_for(:price, duration: '2 years') - price.reload - - expect(price.duration).to eq('2 years') - end - - it 'updates valid_from' do - price = create(:price, valid_from: '2010-07-05') - - patch admin_price_path(price), price: attributes_for(:price, valid_from: '2010-07-06') - price.reload - - expect(price.valid_from).to eq(Time.zone.parse('06.07.2010')) - end - - it 'updates valid_to' do - price = create(:price, valid_to: '2010-07-05') - - patch admin_price_path(price), price: attributes_for(:price, valid_to: '2010-07-06') - price.reload - - expect(price.valid_to).to eq(Time.zone.parse('06.07.2010')) - end - - it 'redirects to :index' do - price = create(:price) - - patch admin_price_path(price), price: attributes_for(:price) - - expect(response).to redirect_to admin_prices_url - end -end diff --git a/spec/requests/admin/dns/zones/create_spec.rb b/spec/requests/admin/dns/zones/create_spec.rb deleted file mode 100644 index 898359ed2..000000000 --- a/spec/requests/admin/dns/zones/create_spec.rb +++ /dev/null @@ -1,36 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'admin zone create', settings: false do - subject(:zone) { DNS::Zone.first } - - before :example do - sign_in_to_admin_area - end - - it 'creates new zone' do - expect { post admin_zones_path, zone: attributes_for(:zone) } - .to change { DNS::Zone.count }.from(0).to(1) - end - - text_attributes = %i[origin email master_nameserver ns_records a_records a4_records] - integer_attributes = %i[ttl refresh retry expire minimum_ttl] - - text_attributes.each do |attr_name| - it "saves #{attr_name}" do - post admin_zones_path, zone: attributes_for(:zone, attr_name => 'test') - expect(zone.send(attr_name)).to eq('test') - end - end - - integer_attributes.each do |attr_name| - it "saves #{attr_name}" do - post admin_zones_path, zone: attributes_for(:zone, attr_name => '1') - expect(zone.send(attr_name)).to eq(1) - end - end - - it 'redirects to :index' do - post admin_zones_path, zone: attributes_for(:zone) - expect(response).to redirect_to admin_zones_url - end -end diff --git a/spec/requests/admin/dns/zones/update_spec.rb b/spec/requests/admin/dns/zones/update_spec.rb deleted file mode 100644 index df0f4bab2..000000000 --- a/spec/requests/admin/dns/zones/update_spec.rb +++ /dev/null @@ -1,40 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'admin zone update', settings: false do - before :example do - sign_in_to_admin_area - end - - text_attributes = %i[origin email master_nameserver ns_records a_records a4_records] - integer_attributes = %i[ttl refresh retry expire minimum_ttl] - - text_attributes.each do |attr_name| - it "updates #{attr_name}" do - zone = create(:zone, attr_name => 'test') - - patch admin_zone_path(zone), zone: attributes_for(:zone, attr_name => 'new-test') - zone.reload - - expect(zone.send(attr_name)).to eq('new-test') - end - end - - integer_attributes.each do |attr_name| - it "updates #{attr_name}" do - zone = create(:zone, attr_name => '1') - - patch admin_zone_path(zone), zone: attributes_for(:zone, attr_name => '2') - zone.reload - - expect(zone.send(attr_name)).to eq(2) - end - end - - it 'redirects to :index' do - zone = create(:zone) - - patch admin_zone_path(zone), zone: attributes_for(:zone) - - expect(response).to redirect_to admin_zones_url - end -end diff --git a/spec/requests/admin/settings/create_spec.rb b/spec/requests/admin/settings/create_spec.rb deleted file mode 100644 index c9e7e443d..000000000 --- a/spec/requests/admin/settings/create_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'Admin settings saving' do - before do - sign_in_to_admin_area - end - - it 'saves integer setting' do - allow(Setting).to receive(:integer_settings) { %i[test_setting] } - post admin_settings_path, settings: { test_setting: '1' } - expect(Setting.test_setting).to eq(1) - end - - it 'saves float setting' do - allow(Setting).to receive(:float_settings) { %i[test_setting] } - post admin_settings_path, settings: { test_setting: '1.2' } - expect(Setting.test_setting).to eq(1.2) - end - - it 'saves boolean setting' do - allow(Setting).to receive(:boolean_settings) { %i[test_setting] } - post admin_settings_path, settings: { test_setting: 'true' } - expect(Setting.test_setting).to be true - end - - it 'saves string setting' do - post admin_settings_path, settings: { test_setting: 'test' } - expect(Setting.test_setting).to eq('test') - end - - it 'redirects to :index' do - post admin_settings_path, settings: { test: 'test' } - expect(response).to redirect_to admin_settings_path - end -end diff --git a/spec/requests/admin/zonefiles/create_spec.rb b/spec/requests/admin/zonefiles/create_spec.rb deleted file mode 100644 index e9dfb62c8..000000000 --- a/spec/requests/admin/zonefiles/create_spec.rb +++ /dev/null @@ -1,14 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'Admin area zone file generation', settings: false do - let!(:zone) { create(:zone, origin: 'com') } - - before do - sign_in_to_admin_area - end - - it 'generates new' do - post admin_zonefiles_path(origin: 'com') - expect(response).to be_success - end -end diff --git a/spec/requests/epp/contact/create/ident_spec.rb b/spec/requests/epp/contact/create/ident_spec.rb deleted file mode 100644 index f4f785f4a..000000000 --- a/spec/requests/epp/contact/create/ident_spec.rb +++ /dev/null @@ -1,292 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP contact:create' do - let(:registrar) { create(:registrar) } - let(:user) { create(:api_user_epp, registrar: registrar) } - let(:session_id) { create(:epp_session, user: user).session_id } - let(:request) { post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" } - - before do - Setting.address_processing = false - sign_in user - end - - context 'when all ident params are valid' do - let(:ident) { Contact.first.identifier } - let(:request_xml) { <<-XML - - - - - - - test - - +1.2 - test@test.com - - - - - test - - - - - XML - } - - it 'creates a contact' do - expect { request }.to change { Contact.count }.from(0).to(1) - end - - it 'saves ident type' do - request - expect(ident.type).to eq('priv') - end - - it 'saves ident country code' do - request - expect(ident.country_code).to eq('US') - end - - specify do - request - expect(epp_response).to have_result(:success) - end - end - - context 'when code is blank' do - let(:request_xml) { <<-XML - - - - - - - test - - +1.2 - test@test.com - - - - - - - - - - XML - } - - it 'does not create a contact' do - expect { request }.to_not change { Contact.count } - end - - specify do - request - expect(epp_response).to have_result(:required_param_missing, - 'Required parameter missing: extension > extdata > ident [ident]') - end - end - - context 'when code is not valid national id' do - let(:request_xml) { <<-XML - - - - - - - test - - +1.2 - test@test.com - - - - - invalid - - - - - XML - } - - before do - country_specific_validations = { - Country.new('DE') => proc { false }, - } - - allow(Contact::Ident::NationalIdValidator).to receive(:country_specific_validations) - .and_return(country_specific_validations) - end - - it 'does not create a contact' do - expect { request }.to_not change { Contact.count } - end - - specify do - request - - message = 'Ident code does not conform to national identification number format of Germany' - expect(epp_response).to have_result(:param_syntax_error, message) - end - end - - context 'when code is not valid registration number' do - let(:request_xml) { <<-XML - - - - - - - test - - +1.2 - test@test.com - - - - - invalid - - - - - XML - } - - before do - country_specific_formats = { - Country.new('DE') => /\Avalid\z/, - } - - allow(Contact::Ident::RegNoValidator).to receive(:country_specific_formats).and_return(country_specific_formats) - end - - it 'does not create a contact' do - expect { request }.to_not change { Contact.count } - end - - specify do - request - expect(epp_response).to have_result(:param_syntax_error, - 'Ident code does not conform to registration number format of Germany') - end - end - - context 'when country code is absent' do - let(:request_xml) { <<-XML - - - - - - - test - - +1.2 - test@test.com - - - - - test - - - - - XML - } - - it 'does not create a contact' do - expect { request }.to_not change { Contact.count } - end - - specify do - request - expect(epp_response).to have_result(:required_param_missing, - 'Required ident attribute missing: cc') - end - end - - context 'when country code is blank' do - let(:request_xml) { <<-XML - - - - - - - test - - +1.2 - test@test.com - - - - - test - - - - - XML - } - - it 'does not create a contact' do - expect { request }.to_not change { Contact.count } - end - - specify do - request - expect(epp_response).to have_result(:syntax_error) - end - end - - context 'when mismatches' do - let(:request_xml) { <<-XML - - - - - - - test - - +1.2 - test@test.com - - - - - test - - - - - XML - } - - before do - mismatches = [ - Contact::Ident::MismatchValidator::Mismatch.new('priv', Country.new('DE')) - ] - allow(Contact::Ident::MismatchValidator).to receive(:mismatches).and_return(mismatches) - end - - it 'does not create a contact' do - expect { request }.to_not change { Contact.count } - end - - specify do - request - expect(epp_response).to have_result(:param_syntax_error, - 'Ident type "priv" is invalid for Germany') - end - end -end diff --git a/spec/requests/epp/contact/create/phone_spec.rb b/spec/requests/epp/contact/create/phone_spec.rb deleted file mode 100644 index fa340abf6..000000000 --- a/spec/requests/epp/contact/create/phone_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -require 'rails_helper' -require_relative '../shared/phone' - -RSpec.describe 'EPP contact:create' do - let(:registrar) { create(:registrar) } - let(:user) { create(:api_user_epp, registrar: registrar) } - let(:session_id) { create(:epp_session, user: user).session_id } - let(:request) { post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" } - let(:request_xml) { <<-XML - - - - - - - test - - #{phone} - test@test.com - - - - - 123456 - - - - - XML - } - - before do - sign_in user - allow(Contact).to receive(:address_processing?).and_return(false) - end - - include_examples 'EPP contact phone' -end diff --git a/spec/requests/epp/contact/create_spec.rb b/spec/requests/epp/contact/create_spec.rb deleted file mode 100644 index 3d461a041..000000000 --- a/spec/requests/epp/contact/create_spec.rb +++ /dev/null @@ -1,126 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP contact:create' do - let(:registrar) { create(:registrar) } - let(:user) { create(:api_user_epp, registrar: registrar) } - let(:session_id) { create(:epp_session, user: user).session_id } - let(:request_xml_with_address) { ' - - - - - - test name - - test street - test city - 12345 - US - - - +372.1234567 - test@example.com - - - - - 1234567 - dGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCg - - - - ABC-12345 - - ' - } - subject(:response_xml) { Nokogiri::XML(response.body) } - subject(:response_code) { response_xml.xpath('//xmlns:result').first['code'] } - subject(:response_description) { response_xml.css('result msg').text } - subject(:address_saved) { Contact.last.attributes.slice(*Contact.address_attribute_names).compact.any? } - - before do - sign_in user - end - - context 'when address processing is enabled' do - before do - allow(Contact).to receive(:address_processing?).and_return(true) - end - - context 'with address' do - it 'returns epp code of 1000' do - post '/epp/command/create', { frame: request_xml_with_address }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response_code).to eq('1000') - end - - it 'returns epp description' do - post '/epp/command/create', { frame: request_xml_with_address}, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response_description).to eq('Command completed successfully') - end - - it 'saves address' do - post '/epp/command/create', { frame: request_xml_with_address }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(address_saved).to be_truthy - end - end - end - - context 'when address processing is disabled' do - before do - allow(Contact).to receive(:address_processing?).and_return(false) - end - - context 'with address' do - it 'returns epp code of 1100' do - post '/epp/command/create', { frame: request_xml_with_address }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response_code).to eq('1100') - end - - it 'returns epp description' do - post '/epp/command/create', { frame: request_xml_with_address }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response_description).to eq('Command completed successfully; Postal address data discarded') - end - - it 'does not save address' do - post '/epp/command/create', { frame: request_xml_with_address }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(address_saved).to be_falsey - end - end - - context 'without address' do - let(:request_xml_without_address) { ' - - - - - - test name - - +372.1234567 - test@test.com - - - - - 123456 - dGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCg - - - - ABC-12345 - - ' - } - - it 'returns epp code of 1000' do - post '/epp/command/create', { frame: request_xml_without_address }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response_code).to eq('1000') - end - - it 'returns epp description' do - post '/epp/command/create', { frame: request_xml_without_address }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response_description).to eq('Command completed successfully') - end - end - end -end diff --git a/spec/requests/epp/contact/info_spec.rb b/spec/requests/epp/contact/info_spec.rb deleted file mode 100644 index dcfbcbede..000000000 --- a/spec/requests/epp/contact/info_spec.rb +++ /dev/null @@ -1,60 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP contact:update' do - let(:registrar) { create(:registrar) } - let(:user) { create(:api_user_epp, registrar: registrar) } - let(:session_id) { create(:epp_session, user: user).session_id } - let(:request_xml) { ' - - - - - test - - - - ' - } - subject(:response_xml) { Nokogiri::XML(response.body) } - subject(:response_code) { response_xml.xpath('//xmlns:result').first['code'] } - subject(:address_count) { response_xml - .xpath('//contact:addr', contact: 'https://epp.tld.ee/schema/contact-ee-1.1.xsd') - .count } - - before do - sign_in user - create(:contact, code: 'TEST') - end - - context 'when address processing is enabled' do - before do - allow(Contact).to receive(:address_processing?).and_return(true) - end - - it 'returns epp code of 1000' do - post '/epp/command/info', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response_code).to eq('1000') - end - - it 'returns address' do - post '/epp/command/info', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(address_count).to_not be_zero - end - end - - context 'when address processing is disabled' do - before do - allow(Contact).to receive(:address_processing?).and_return(false) - end - - it 'returns epp code of 1000' do - post '/epp/command/info', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response_code).to eq('1000') - end - - it 'does not return address' do - post '/epp/command/info', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(address_count).to be_zero - end - end -end diff --git a/spec/requests/epp/contact/shared/phone.rb b/spec/requests/epp/contact/shared/phone.rb deleted file mode 100644 index 3ae9f22df..000000000 --- a/spec/requests/epp/contact/shared/phone.rb +++ /dev/null @@ -1,28 +0,0 @@ -RSpec.shared_examples 'EPP contact phone' do - context 'when phone is valid' do - let(:phone) { '+123.4' } - - specify do - request - expect(response).to have_code_of(1000) - end - end - - context 'when phone has invalid format' do - let(:phone) { '1234' } - - specify do - request - expect(response).to have_code_of(2005) - end - end - - context 'when phone has only zeros' do - let(:phone) { '+000.0' } - - specify do - request - expect(response).to have_code_of(2005) - end - end -end diff --git a/spec/requests/epp/contact/update/ident_spec.rb b/spec/requests/epp/contact/update/ident_spec.rb deleted file mode 100644 index 25f57389f..000000000 --- a/spec/requests/epp/contact/update/ident_spec.rb +++ /dev/null @@ -1,199 +0,0 @@ -require 'rails_helper' - -# https://github.com/internetee/registry/issues/576 - -RSpec.describe 'EPP contact:update' do - let(:registrar) { create(:registrar) } - let(:user) { create(:api_user_epp, registrar: registrar) } - let(:session_id) { create(:epp_session, user: user).session_id } - let(:ident) { contact.identifier } - let(:request) { post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" } - let(:request_xml) { <<-XML - - - - - - TEST - - - test - - - - - - - test - - - - - XML - } - - before do - sign_in user - end - - context 'when contact ident is valid' do - context 'when submitted ident matches current one' do - let!(:contact) { create(:contact, code: 'TEST', - ident: 'test', - ident_type: 'priv', - ident_country_code: 'US') } - - specify do - request - expect(epp_response).to have_result(:success) - end - end - - context 'when submitted ident does not match current one' do - let!(:contact) { create(:contact, code: 'TEST', - ident: 'another-test', - ident_type: 'priv', - ident_country_code: 'US') } - - it 'does not update code' do - expect do - request - contact.reload - end.to_not change { ident.code } - end - - it 'does not update type' do - expect do - request - contact.reload - end.to_not change { ident.type } - end - - it 'does not update country code' do - expect do - request - contact.reload - end.to_not change { ident.country_code } - end - - specify do - request - - expect(epp_response).to have_result(:data_management_policy_violation, - t('epp.contacts.errors.valid_ident')) - end - end - end - - context 'when contact ident is invalid' do - let(:contact) { build(:contact, code: 'TEST', ident: 'test', ident_type: nil, ident_country_code: nil) } - - before do - contact.save(validate: false) - end - - context 'when submitted ident is the same as current one' do - let(:request_xml) { <<-XML - - - - - - TEST - - - test - - - - - - - test - - - - - XML - } - - it 'does not update code' do - expect do - request - contact.reload - end.to_not change { ident.code } - end - - it 'updates type' do - request - contact.reload - expect(ident.type).to eq('priv') - end - - it 'updates country code' do - request - contact.reload - expect(ident.country_code).to eq('US') - end - - specify do - request - expect(epp_response).to have_result(:success) - end - end - - context 'when submitted ident is different from current one' do - let(:request_xml) { <<-XML - - - - - - TEST - - - test - - - - - - - another-test - - - - - XML - } - - it 'does not update code' do - expect do - request - contact.reload - end.to_not change { ident.code } - end - - it 'does not update type' do - expect do - request - contact.reload - end.to_not change { ident.type } - end - - it 'does not update country code' do - expect do - request - contact.reload - end.to_not change { ident.country_code } - end - - specify do - request - - expect(epp_response).to have_result(:data_management_policy_violation, - t('epp.contacts.errors.ident_update')) - end - end - end -end diff --git a/spec/requests/epp/contact/update/phone_spec.rb b/spec/requests/epp/contact/update/phone_spec.rb deleted file mode 100644 index 9955308b6..000000000 --- a/spec/requests/epp/contact/update/phone_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -require 'rails_helper' -require_relative '../shared/phone' - -RSpec.describe 'EPP contact:update' do - let(:registrar) { create(:registrar) } - let(:user) { create(:api_user_epp, registrar: registrar) } - let(:session_id) { create(:epp_session, user: user).session_id } - let!(:contact) { create(:contact, code: 'TEST') } - let(:request) { post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" } - let(:request_xml) { <<-XML - - - - - - TEST - - #{phone} - - - - - - XML - } - - before do - sign_in user - allow(Contact).to receive(:address_processing?).and_return(false) - end - - include_examples 'EPP contact phone' -end diff --git a/spec/requests/epp/contact/update_spec.rb b/spec/requests/epp/contact/update_spec.rb deleted file mode 100644 index 9ac3a99bb..000000000 --- a/spec/requests/epp/contact/update_spec.rb +++ /dev/null @@ -1,108 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP contact:update' do - let(:registrar) { create(:registrar) } - let(:user) { create(:api_user_epp, registrar: registrar) } - let(:session_id) { create(:epp_session, user: user).session_id } - let(:request_xml_with_address) { ' - - - - - test - - - - test street - test city - 12345 - DE - - - - - - - - dGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCg - - - ABC-12345 - - ' - } - subject(:response_xml) { Nokogiri::XML(response.body) } - subject(:response_code) { response_xml.xpath('//xmlns:result').first['code'] } - subject(:response_description) { response_xml.css('result msg').text } - - before do - sign_in user - create(:contact, code: 'TEST') - end - - context 'when address processing is enabled' do - before do - allow(Contact).to receive(:address_processing?).and_return(true) - end - - context 'with address' do - it 'returns epp code of 1000' do - post '/epp/command/update', { frame: request_xml_with_address }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response_code).to eq('1000') - end - - it 'returns epp description' do - post '/epp/command/update', { frame: request_xml_with_address }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response_description).to eq('Command completed successfully') - end - end - end - - context 'when address processing is disabled' do - before do - allow(Contact).to receive(:address_processing?).and_return(false) - end - - context 'with address' do - it 'returns epp code of 1100' do - post '/epp/command/update', { frame: request_xml_with_address }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response_code).to eq('1100') - end - - it 'returns epp description' do - post '/epp/command/update', { frame: request_xml_with_address }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response_description).to eq('Command completed successfully; Postal address data discarded') - end - end - - context 'without address' do - let(:request_xml_without_address) { ' - - - - - test - - - - - dGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCgdGVzdCBmYWlsCg - - - ABC-12345 - - ' - } - - it 'returns epp code of 1000' do - post '/epp/command/update', { frame: request_xml_without_address }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response_code).to eq('1000') - end - - it 'returns epp description' do - post '/epp/command/update', { frame: request_xml_without_address }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response_description).to eq('Command completed successfully') - end - end - end -end diff --git a/spec/requests/epp/domain/create/account_balance_spec.rb b/spec/requests/epp/domain/create/account_balance_spec.rb deleted file mode 100644 index 1692a1797..000000000 --- a/spec/requests/epp/domain/create/account_balance_spec.rb +++ /dev/null @@ -1,68 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP domain:create', settings: false do - let(:session_id) { create(:epp_session, user: user).session_id } - let(:request) { post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" } - let!(:user) { create(:api_user_epp, registrar: registrar) } - let!(:contact) { create(:contact, code: 'test') } - let!(:zone) { create(:zone, origin: 'test') } - let!(:price) { create(:price, - duration: '1 year', - price: Money.from_amount(1), - operation_category: 'create', - valid_from: Time.zone.parse('05.07.2010'), - valid_to: Time.zone.parse('05.07.2010'), - zone: zone) - } - let(:request_xml) { <<-XML - - - - - - test.test - test - - - - - #{valid_legal_document} - - - - - XML - } - - before :example do - travel_to Time.zone.parse('05.07.2010') - Setting.days_to_renew_domain_before_expire = 0 - sign_in user - end - - context 'when account balance is sufficient' do - let!(:registrar) { create(:registrar_with_unlimited_balance) } - - it 'creates domain' do - expect { request }.to change { Domain.count }.from(0).to(1) - end - - specify do - request - expect(response).to have_code_of(1000) - end - end - - context 'when account balance is not sufficient' do - let!(:registrar) { create(:registrar_with_zero_balance) } - - it 'does not create domain' do - expect { request }.to_not change { Domain.count } - end - - specify do - request - expect(response).to have_code_of(2104) - end - end -end diff --git a/spec/requests/epp/domain/create/default_period_spec.rb b/spec/requests/epp/domain/create/default_period_spec.rb deleted file mode 100644 index bb83d5aba..000000000 --- a/spec/requests/epp/domain/create/default_period_spec.rb +++ /dev/null @@ -1,60 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP domain:create', settings: false do - let(:session_id) { create(:epp_session, user: user).session_id } - let(:request) { post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" } - let!(:user) { create(:api_user_epp, registrar: registrar) } - let!(:contact) { create(:contact, code: 'test') } - let!(:zone) { create(:zone, origin: 'test') } - let!(:registrar) { create(:registrar_with_unlimited_balance) } - let!(:price) { create(:price, - duration: '1 year', - price: Money.from_amount(1), - operation_category: 'create', - valid_from: Time.zone.parse('05.07.2010'), - valid_to: Time.zone.parse('05.07.2010'), - zone: zone) - } - let(:request_xml) { <<-XML - - - - - - test.test - test - - - - - #{valid_legal_document} - - - - - XML - } - - before :example do - travel_to Time.zone.parse('05.07.2010 10:30') - Setting.days_to_renew_domain_before_expire = 0 - sign_in user - end - - context 'when period is absent' do - it 'creates domain' do - expect { request }.to change { Domain.count }.from(0).to(1) - end - - it 'uses default duration of 1 year' do - request - expire_time = (Time.zone.parse('05.07.2010') + 1.year + 1.day).beginning_of_day - expect(Domain.first.expire_time).to eq(expire_time) - end - - specify do - request - expect(response).to have_code_of(1000) - end - end -end diff --git a/spec/requests/epp/domain/create/optional_nameserver_spec.rb b/spec/requests/epp/domain/create/optional_nameserver_spec.rb deleted file mode 100644 index da409d0b9..000000000 --- a/spec/requests/epp/domain/create/optional_nameserver_spec.rb +++ /dev/null @@ -1,110 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP domain:create', settings: false do - let(:session_id) { create(:epp_session, user: user).session_id } - let(:request) { post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" } - let!(:registrar) { create(:registrar_with_unlimited_balance) } - let!(:user) { create(:api_user_epp, registrar: registrar) } - let!(:contact) { create(:contact, code: 'test') } - let!(:zone) { create(:zone, origin: 'test') } - let!(:price) { create(:price, - duration: '1 year', - price: Money.from_amount(1), - operation_category: 'create', - valid_from: Time.zone.parse('05.07.2010'), - valid_to: Time.zone.parse('05.07.2010'), - zone: zone) - } - - before :example do - travel_to Time.zone.parse('05.07.2010') - sign_in user - end - - context 'when nameserver is optional' do - before :example do - allow(Domain).to receive(:nameserver_required?).and_return(false) - end - - context 'when minimum nameserver count requirement is not satisfied' do - let(:request_xml) { <<-XML - - - - - - test.test - 1 - - - ns.test.com - 192.168.1.1 - - - test - - - - - #{valid_legal_document} - - - - - XML - } - - before :example do - Setting.ns_min_count = 2 - end - - it 'does not create domain' do - expect { request }.to_not change { Domain.count } - end - - specify do - request - expect(response).to have_code_of(2308) - end - end - - context 'when nameserver is absent' do - let(:request_xml) { <<-XML - - - - - - test.test - 1 - test - - - - - #{valid_legal_document} - - - - - XML - } - - it 'creates new domain' do - expect { request }.to change { Domain.count }.from(0).to(1) - end - - describe 'new domain' do - it 'has status of inactive' do - request - expect(Domain.first.statuses).to include(DomainStatus::INACTIVE) - end - end - - specify do - request - expect(response).to have_code_of(1000) - end - end - end -end diff --git a/spec/requests/epp/domain/create/period_spec.rb b/spec/requests/epp/domain/create/period_spec.rb deleted file mode 100644 index c9c7e163a..000000000 --- a/spec/requests/epp/domain/create/period_spec.rb +++ /dev/null @@ -1,109 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP domain:create', settings: false do - let(:session_id) { create(:epp_session, user: user).session_id } - let(:request) { post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" } - let!(:user) { create(:api_user_epp, registrar: registrar) } - let!(:contact) { create(:contact, code: 'test') } - let!(:zone) { create(:zone, origin: 'test') } - let!(:registrar) { create(:registrar_with_unlimited_balance) } - - before :example do - travel_to Time.zone.parse('05.07.2010 10:30') - Setting.days_to_renew_domain_before_expire = 0 - sign_in user - end - - context 'when period is 3 months' do - let!(:price) { create(:price, - duration: '3 mons', - price: Money.from_amount(1), - operation_category: 'create', - valid_from: Time.zone.parse('05.07.2010'), - valid_to: Time.zone.parse('05.07.2010'), - zone: zone) - } - let(:request_xml) { <<-XML - - - - - - test.test - 3 - test - - - - - #{valid_legal_document} - - - - - XML - } - - - it 'creates domain' do - expect { request }.to change { Domain.count }.from(0).to(1) - end - - specify 'expire_time' do - request - expire_time = (Time.zone.parse('05.07.2010 10:30') + 3.months + 1.day).beginning_of_day - expect(Domain.first.expire_time).to eq(expire_time) - end - - specify do - request - expect(response).to have_code_of(1000) - end - end - - context 'when period is 10 years' do - let!(:price) { create(:price, - duration: '10 years', - price: Money.from_amount(1), - operation_category: 'create', - valid_from: Time.zone.parse('05.07.2010'), - valid_to: Time.zone.parse('05.07.2010'), - zone: zone) - } - let(:request_xml) { <<-XML - - - - - - test.test - 10 - test - - - - - #{valid_legal_document} - - - - - XML - } - - it 'creates domain' do - expect { request }.to change { Domain.count }.from(0).to(1) - end - - specify 'expire_time' do - request - expire_time = (Time.zone.parse('05.07.2010 10:30') + 10.years + 1.day).beginning_of_day - expect(Domain.first.expire_time).to eq(expire_time) - end - - specify do - request - expect(response).to have_code_of(1000) - end - end -end diff --git a/spec/requests/epp/domain/create/price_spec.rb b/spec/requests/epp/domain/create/price_spec.rb deleted file mode 100644 index b158bd7af..000000000 --- a/spec/requests/epp/domain/create/price_spec.rb +++ /dev/null @@ -1,67 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP domain:create', settings: false do - let(:session_id) { create(:epp_session, user: user).session_id } - let(:request) { post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" } - let!(:user) { create(:api_user_epp, registrar: registrar) } - let!(:contact) { create(:contact, code: 'test') } - let!(:zone) { create(:zone, origin: 'test') } - let!(:registrar) { create(:registrar_with_unlimited_balance) } - let(:request_xml) { <<-XML - - - - - - test.test - 1 - test - - - - - #{valid_legal_document} - - - - - XML - } - - before :example do - travel_to Time.zone.parse('05.07.2010') - Setting.days_to_renew_domain_before_expire = 0 - sign_in user - end - - context 'when price is present' do - let!(:price) { create(:price, - duration: '1 year', - price: Money.from_amount(1), - operation_category: 'create', - valid_from: Time.zone.parse('05.07.2010'), - valid_to: Time.zone.parse('05.07.2010'), - zone: zone) - } - - it 'creates domain' do - expect { request }.to change { Domain.count }.from(0).to(1) - end - - specify do - request - expect(response).to have_code_of(1000) - end - end - - context 'when price is absent' do - it 'does not create domain' do - expect { request }.to_not change { Domain.count } - end - - specify do - request - expect(response).to have_code_of(2104) - end - end -end diff --git a/spec/requests/epp/domain/create/required_nameserver_spec.rb b/spec/requests/epp/domain/create/required_nameserver_spec.rb deleted file mode 100644 index cb21bc150..000000000 --- a/spec/requests/epp/domain/create/required_nameserver_spec.rb +++ /dev/null @@ -1,100 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP domain:create', settings: false do - let(:session_id) { create(:epp_session, user: user).session_id } - let(:request) { post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" } - let!(:registrar) { create(:registrar_with_unlimited_balance) } - let!(:user) { create(:api_user_epp, registrar: registrar) } - let!(:contact) { create(:contact, code: 'test') } - let!(:zone) { create(:zone, origin: 'test') } - let!(:price) { create(:price, - duration: '1 year', - price: Money.from_amount(1), - operation_category: 'create', - valid_from: Time.zone.parse('05.07.2010'), - valid_to: Time.zone.parse('05.07.2010'), - zone: zone) - } - - before :example do - travel_to Time.zone.parse('05.07.2010') - sign_in user - end - - context 'when nameserver is required' do - before :example do - allow(Domain).to receive(:nameserver_required?).and_return(true) - Setting.ns_min_count = 1 - end - - context 'when minimum nameserver count requirement is satisfied' do - let(:request_xml) { <<-XML - - - - - - test.test - 1 - - - ns.test.com - 192.168.1.1 - - - test - - - - - #{valid_legal_document} - - - - - XML - } - - it 'creates new domain' do - expect { request }.to change { Domain.count }.from(0).to(1) - end - - specify do - request - expect(response).to have_code_of(1000) - end - end - - context 'when nameservers are absent' do - let(:request_xml) { <<-XML - - - - - - test.test - 1 - test - - - - - #{valid_legal_document} - - - - - XML - } - - it 'does not create domain' do - expect { request }.to_not change { Domain.count } - end - - specify do - request - expect(response).to have_code_of(2003) - end - end - end -end diff --git a/spec/requests/epp/domain/renew/account_balance_spec.rb b/spec/requests/epp/domain/renew/account_balance_spec.rb deleted file mode 100644 index 7670dcd75..000000000 --- a/spec/requests/epp/domain/renew/account_balance_spec.rb +++ /dev/null @@ -1,92 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP domain:renew' do - let(:session_id) { create(:epp_session, user: user).session_id } - let(:request) { post '/epp/command/renew', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" } - let!(:user) { create(:api_user_epp, registrar: registrar) } - let!(:zone) { create(:zone, origin: 'test') } - let!(:price) { create(:price, - duration: '1 year', - price: Money.from_amount(1), - operation_category: 'renew', - valid_from: Time.zone.parse('05.07.2010'), - valid_to: Time.zone.parse('05.07.2010'), - zone: zone) - } - - before :example do - Setting.days_to_renew_domain_before_expire = 0 - travel_to Time.zone.parse('05.07.2010') - sign_in user - end - - context 'when account balance is sufficient' do - let!(:registrar) { create(:registrar_with_unlimited_balance) } - let!(:domain) { create(:domain, - registrar: registrar, - name: 'test.test', - expire_time: Time.zone.parse('05.07.2010')) - } - let(:request_xml) { <<-XML - - - - - - test.test - 2010-07-05 - 1 - - - - - XML - } - - it 'renews domain' do - request - domain.reload - expect(domain.expire_time).to eq(Time.zone.parse('05.07.2011')) - end - - specify do - request - expect(response).to have_code_of(1000) - end - end - - context 'when account balance is not sufficient' do - let!(:registrar) { create(:registrar_with_zero_balance) } - let!(:domain) { create(:domain, - registrar: registrar, - name: 'test.test', - expire_time: Time.zone.parse('05.07.2010')) - } - let(:request_xml) { <<-XML - - - - - - test.test - 2010-07-04 - 1 - - - - - XML - } - - it 'does not renew domain' do - request - domain.reload - expect(domain.expire_time).to eq(Time.zone.parse('05.07.2010')) - end - - specify do - request - expect(response).to have_code_of(2104) - end - end -end diff --git a/spec/requests/epp/domain/renew/default_period_spec.rb b/spec/requests/epp/domain/renew/default_period_spec.rb deleted file mode 100644 index dd0806806..000000000 --- a/spec/requests/epp/domain/renew/default_period_spec.rb +++ /dev/null @@ -1,56 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP domain:renew', settings: false do - let(:session_id) { create(:epp_session, user: user).session_id } - let(:request) { post '/epp/command/renew', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" } - let!(:user) { create(:api_user_epp, registrar: registrar) } - let!(:zone) { create(:zone, origin: 'test') } - let!(:registrar) { create(:registrar_with_unlimited_balance) } - let!(:price) { create(:price, - duration: '1 year', - price: Money.from_amount(1), - operation_category: 'renew', - valid_from: Time.zone.parse('05.07.2010'), - valid_to: Time.zone.parse('05.07.2010'), - zone: zone) - } - let!(:domain) { create(:domain, - registrar: registrar, - name: 'test.test', - expire_time: Time.zone.parse('05.07.2010')) - } - let(:request_xml) { <<-XML - - - - - - test.test - 2010-07-05 - 1 - - - - - XML - } - - before :example do - travel_to Time.zone.parse('05.07.2010') - Setting.days_to_renew_domain_before_expire = 0 - sign_in user - end - - context 'when period is absent' do - it 'renews domain for 1 year' do - request - domain.reload - expect(domain.expire_time).to eq(Time.zone.parse('05.07.2011')) - end - - specify do - request - expect(response).to have_code_of(1000) - end - end -end diff --git a/spec/requests/epp/domain/renew/expire_time_spec.rb b/spec/requests/epp/domain/renew/expire_time_spec.rb deleted file mode 100644 index 385b2ba5e..000000000 --- a/spec/requests/epp/domain/renew/expire_time_spec.rb +++ /dev/null @@ -1,89 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP domain:renew' do - let(:session_id) { create(:epp_session, user: user).session_id } - let(:request) { post '/epp/command/renew', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" } - let!(:user) { create(:api_user_epp, registrar: registrar) } - let!(:registrar) { create(:registrar_with_unlimited_balance) } - let!(:zone) { create(:zone, origin: 'test') } - let!(:price) { create(:price, - duration: '1 year', - price: Money.from_amount(1), - operation_category: 'renew', - valid_from: Time.zone.parse('05.07.2010'), - valid_to: Time.zone.parse('05.07.2010'), - zone: zone) - } - - before :example do - Setting.days_to_renew_domain_before_expire = 0 - travel_to Time.zone.parse('05.07.2010') - sign_in user - end - - context 'when given expire time and current match' do - let!(:domain) { create(:domain, - registrar: registrar, - name: 'test.test', - expire_time: Time.zone.parse('05.07.2010')) - } - let(:request_xml) { <<-XML - - - - - - test.test - 2010-07-05 - 1 - - - - - XML - } - - it 'renews domain' do - request - domain.reload - expect(domain.expire_time).to eq(Time.zone.parse('05.07.2011')) - end - - specify do - request - expect(response).to have_code_of(1000) - end - end - - context 'when given expire time and current do not match' do - let!(:domain) { create(:domain, - registrar: registrar, - name: 'test.test', - expire_time: Time.zone.parse('05.07.2010')) - } - let(:request_xml) { <<-XML - - - - - - test.test - 2010-07-04 - 1 - - - - - XML - } - - it 'does not renew domain' do - expect { request; domain.reload }.to_not change { domain.expire_time } - end - - specify do - request - expect(response).to have_code_of(2306) - end - end -end diff --git a/spec/requests/epp/domain/renew/max_expire_time_spec.rb b/spec/requests/epp/domain/renew/max_expire_time_spec.rb deleted file mode 100644 index 79362aa15..000000000 --- a/spec/requests/epp/domain/renew/max_expire_time_spec.rb +++ /dev/null @@ -1,92 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP domain:renew' do - let(:session_id) { create(:epp_session, user: user).session_id } - let(:user) { create(:api_user_epp, registrar: registrar) } - let(:registrar) { create(:registrar_with_unlimited_balance) } - let!(:zone) { create(:zone, origin: 'test') } - let!(:price) { create(:price, - duration: '10 years', - price: Money.from_amount(1), - operation_category: 'renew', - valid_from: Time.zone.parse('05.07.2010'), - valid_to: Time.zone.parse('05.07.2010'), - zone: zone) - } - subject(:response_xml) { Nokogiri::XML(response.body) } - subject(:response_code) { response_xml.xpath('//xmlns:result').first['code'] } - subject(:response_description) { response_xml.css('result msg').text } - - before :example do - travel_to Time.zone.parse('05.07.2010') - Setting.days_to_renew_domain_before_expire = 0 - sign_in user - end - - context 'when domain can be renewed' do - let!(:domain) { create(:domain, - registrar: registrar, - name: 'test.test', - expire_time: Time.zone.parse('05.07.2010')) - } - let(:request_xml) { <<-XML - - - - - - test.test - 2010-07-05 - 10 - - - - - XML - } - - it 'returns epp code of 1000' do - post '/epp/command/renew', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response_code).to eq('1000') - end - - it 'returns epp description' do - post '/epp/command/renew', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response_description).to eq('Command completed successfully') - end - end - - context 'when domain cannot be renewed' do - let!(:domain) { create(:domain, - registrar: registrar, - name: 'test.test', - expire_time: Time.zone.parse('05.07.2011')) - } - let(:request_xml) { <<-XML - - - - - - test.test - 2011-07-05 - 10 - - - - - XML - } - - it 'returns epp code of 2105' do - post '/epp/command/renew', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response_code).to eq('2105') - end - - it 'returns epp description' do - post '/epp/command/renew', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response_description).to eq('Object is not eligible for renewal; ' \ - 'Expiration date must be before 2021-07-05') - end - end -end diff --git a/spec/requests/epp/domain/renew/period_spec.rb b/spec/requests/epp/domain/renew/period_spec.rb deleted file mode 100644 index 510e3cf06..000000000 --- a/spec/requests/epp/domain/renew/period_spec.rb +++ /dev/null @@ -1,94 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP domain:renew', settings: false do - let(:session_id) { create(:epp_session, user: user).session_id } - let(:request) { post '/epp/command/renew', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" } - let!(:user) { create(:api_user_epp, registrar: registrar) } - let!(:zone) { create(:zone, origin: 'test') } - let!(:registrar) { create(:registrar_with_unlimited_balance) } - let!(:domain) { create(:domain, - registrar: registrar, - name: 'test.test', - expire_time: Time.zone.parse('05.07.2010 10:30')) - } - - before :example do - travel_to Time.zone.parse('05.07.2010') - Setting.days_to_renew_domain_before_expire = 0 - sign_in user - end - - context 'when period is 3 months' do - let!(:price) { create(:price, - duration: '3 mons', - price: Money.from_amount(1), - operation_category: 'renew', - valid_from: Time.zone.parse('05.07.2010'), - valid_to: Time.zone.parse('05.07.2010'), - zone: zone) - } - let(:request_xml) { <<-XML - - - - - - test.test - 2010-07-05 - 3 - - - - - XML - } - - it 'renews domain for 3 months' do - request - domain.reload - expect(domain.expire_time).to eq(Time.zone.parse('05.10.2010 10:30')) - end - - specify do - request - expect(response).to have_code_of(1000) - end - end - - context 'when period is 10 years' do - let!(:price) { create(:price, - duration: '10 years', - price: Money.from_amount(1), - operation_category: 'renew', - valid_from: Time.zone.parse('05.07.2010'), - valid_to: Time.zone.parse('05.07.2010'), - zone: zone) - } - let(:request_xml) { <<-XML - - - - - - test.test - 2010-07-05 - 10 - - - - - XML - } - - it 'renews domain for 10 years' do - request - domain.reload - expect(domain.expire_time).to eq(Time.zone.parse('05.07.2020 10:30')) - end - - specify do - request - expect(response).to have_code_of(1000) - end - end -end diff --git a/spec/requests/epp/domain/renew/price_spec.rb b/spec/requests/epp/domain/renew/price_spec.rb deleted file mode 100644 index 68ee6b1a9..000000000 --- a/spec/requests/epp/domain/renew/price_spec.rb +++ /dev/null @@ -1,68 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP domain:renew', settings: false do - let(:session_id) { create(:epp_session, user: user).session_id } - let(:request) { post '/epp/command/renew', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" } - let!(:user) { create(:api_user_epp, registrar: registrar) } - let!(:zone) { create(:zone, origin: 'test') } - let!(:registrar) { create(:registrar_with_unlimited_balance) } - let!(:domain) { create(:domain, - registrar: registrar, - name: 'test.test', - expire_time: Time.zone.parse('05.07.2010 10:30')) - } - let(:request_xml) { <<-XML - - - - - - test.test - 2010-07-05 - 1 - - - - - XML - } - - before :example do - travel_to Time.zone.parse('05.07.2010') - Setting.days_to_renew_domain_before_expire = 0 - sign_in user - end - - context 'when price is present' do - let!(:price) { create(:price, - duration: '1 year', - price: Money.from_amount(1), - operation_category: 'renew', - valid_from: Time.zone.parse('05.07.2010'), - valid_to: Time.zone.parse('05.07.2010'), - zone: zone) - } - - it 'renews domain for 1 year' do - request - domain.reload - expect(domain.expire_time).to eq(Time.zone.parse('05.07.2011 10:30')) - end - - specify do - request - expect(response).to have_code_of(1000) - end - end - - context 'when price is absent' do - it 'does not renew domain' do - expect { request; domain.reload }.to_not change { domain.expire_time } - end - - specify do - request - expect(response).to have_code_of(2104) - end - end -end diff --git a/spec/requests/epp/domain/update/nameserver_add_spec.rb b/spec/requests/epp/domain/update/nameserver_add_spec.rb deleted file mode 100644 index ffad74176..000000000 --- a/spec/requests/epp/domain/update/nameserver_add_spec.rb +++ /dev/null @@ -1,95 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP domain:update' do - let(:registrar) { create(:registrar) } - let(:user) { create(:api_user_epp, registrar: registrar) } - let(:session_id) { create(:epp_session, user: user).session_id } - let!(:domain) { create(:domain, name: 'test.com') } - subject(:response_xml) { Nokogiri::XML(response.body) } - subject(:response_code) { response_xml.xpath('//xmlns:result').first['code'] } - subject(:response_description) { response_xml.css('result msg').text } - - before :example do - sign_in user - - allow(Domain).to receive(:nameserver_required?).and_return(false) - Setting.ns_min_count = 2 - Setting.ns_max_count = 3 - end - - context 'when nameserver count is less than minimum' do - let(:request_xml) { <<-XML - - - - - - test.com - - - - ns1.test.ee - - - - - - - - XML - } - - it 'returns epp code of 2308' do - post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response_code).to eq('2308'), "Expected EPP code of 2308, got #{response_code} (#{response_description})" - end - - it 'returns epp description' do - post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" - - description = 'Data management policy violation;' \ - " Nameserver count must be between #{Setting.ns_min_count}-#{Setting.ns_max_count}" \ - ' for active domains [nameservers]' - expect(response_description).to eq(description) - end - end - - context 'when nameserver count satisfies required minimum' do - let!(:domain) { create(:domain, name: 'test.com') } - let(:request_xml) { <<-XML - - - - - - test.com - - - - ns1.test.ee - - - ns2.test.ee - - - - - - - - XML - } - - it 'returns epp code of 1000' do - post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response_code).to eq('1000'), "Expected EPP code of 1000, got #{response_code} (#{response_description})" - end - - it 'removes inactive status' do - post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" - - domain = Domain.find_by(name: 'test.com') - expect(domain.statuses).to_not include(DomainStatus::INACTIVE) - end - end -end diff --git a/spec/requests/epp/domain/update/nameserver_remove_spec.rb b/spec/requests/epp/domain/update/nameserver_remove_spec.rb deleted file mode 100644 index 4fcaa61dc..000000000 --- a/spec/requests/epp/domain/update/nameserver_remove_spec.rb +++ /dev/null @@ -1,108 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP domain:update' do - let(:registrar) { create(:registrar) } - let(:user) { create(:api_user_epp, registrar: registrar) } - let(:session_id) { create(:epp_session, user: user).session_id } - subject(:response_xml) { Nokogiri::XML(response.body) } - subject(:response_code) { response_xml.xpath('//xmlns:result').first['code'] } - subject(:response_description) { response_xml.css('result msg').text } - - before :example do - sign_in user - allow(Domain).to receive(:nameserver_required?).and_return(false) - end - - context 'when remaining nameserver count is less than required minimum' do - let!(:domain) { create(:domain, name: 'test.com') } - let(:request_xml) { <<-XML - - - - - - test.com - - - - ns1.test.ee - - - - - - - - XML - } - - before :example do - Setting.ns_min_count = 2 - Setting.ns_max_count = 3 - - domain.nameservers << create(:nameserver, hostname: 'ns1.test.ee') - domain.nameservers << create(:nameserver, hostname: 'ns2.test.ee') - end - - it 'returns epp code of 2308' do - post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response_code).to eq('2308'), "Expected EPP code of 2308, got #{response_code} (#{response_description})" - end - - it 'returns epp description' do - post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" - - description = 'Data management policy violation;' \ - " Nameserver count must be between #{Setting.ns_min_count}-#{Setting.ns_max_count}" \ - ' for active domains [nameservers]' - expect(response_description).to eq(description) - end - end - - context 'when all nameservers are removed' do - let!(:domain) { create(:domain, name: 'test.com') } - let(:request_xml) { <<-XML - - - - - - test.com - - - - ns1.test.ee - - - ns2.test.ee - - - - - - - - XML - } - - before :example do - domain.nameservers << create(:nameserver, hostname: 'ns1.test.ee') - domain.nameservers << create(:nameserver, hostname: 'ns2.test.ee') - domain.activate - domain.save! - end - - it 'returns epp code of 1000' do - post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response_code).to eq('1000'), "Expected EPP code of 1000, got #{response_code} (#{response_description})" - end - - describe 'domain' do - it 'has status of inactive' do - post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" - domain = Domain.find_by(name: 'test.com') - expect(domain.statuses).to include(DomainStatus::INACTIVE) - end - end - end -end diff --git a/spec/requests/epp/domain/update/registrant_change/same_as_current_spec.rb b/spec/requests/epp/domain/update/registrant_change/same_as_current_spec.rb deleted file mode 100644 index 46ea197da..000000000 --- a/spec/requests/epp/domain/update/registrant_change/same_as_current_spec.rb +++ /dev/null @@ -1,215 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP domain:update' do - let(:registrar) { create(:registrar) } - let(:user) { create(:api_user_epp, registrar: registrar) } - let(:session_id) { create(:epp_session, user: user).session_id } - let(:request) { post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" } - let!(:domain) { create(:domain, name: 'test.com', registrant: registrant) } - - before :example do - sign_in user - end - - context 'when registrant change confirmation is enabled' do - before :example do - Setting.request_confrimation_on_registrant_change_enabled = true - end - - context 'when given registrant is the same as current one' do - let!(:registrant) { create(:registrant, code: 'TEST') } - let(:request_xml) { <<-XML - - - - - - test.com - - TEST - - - - - - #{valid_legal_document} - - - - - XML - } - - specify do - request - expect(response).to have_code_of(1000) - end - - it 'keeps same registrant' do - expect { request; domain.reload }.to_not change { domain.registrant.code } - end - - it 'does not ask for confirmation' do - request - domain.reload - expect(domain.registrant_verification_asked?).to be false - end - - it 'does not send confirmation and notice emails' do - expect { request }.to_not change { ActionMailer::Base.deliveries.count } - end - end - - context 'when given registrant is different than current one' do - let!(:registrant) { create(:registrant, code: 'OLD-CODE') } - let!(:new_registrant) { create(:registrant, code: 'NEW-CODE') } - let(:request_xml) { <<-XML - - - - - - test.com - - NEW-CODE - - - - - - #{valid_legal_document} - - - - - XML - } - - specify do - request - expect(response).to have_code_of(1001) - end - - it 'does not change registrant without confirmation' do - expect { request; domain.reload }.to_not change { domain.registrant.code } - end - - it 'asks for confirmation' do - request - domain.reload - expect(domain.registrant_verification_asked?).to be true - end - - it 'sets PENDING_UPDATE status' do - request - domain.reload - expect(domain.statuses).to include(DomainStatus::PENDING_UPDATE) - end - - it 'sends confirmation and notice emails' do - expect { request }.to change { ActionMailer::Base.deliveries.count }.by(2) - end - end - end - - context 'when registrant change confirmation is disabled' do - before :example do - Setting.request_confrimation_on_registrant_change_enabled = false - end - - context 'when given registrant is the same as current one' do - let!(:registrant) { create(:registrant, code: 'TEST') } - let(:request_xml) { <<-XML - - - - - - test.com - - TEST - - - - - - #{valid_legal_document} - - - - - XML - } - - specify do - request - expect(response).to have_code_of(1000) - end - - it 'keeps same registrant' do - expect { request; domain.reload }.to_not change { domain.registrant.code } - end - - it 'does not ask for confirmation' do - request - domain.reload - expect(domain.registrant_verification_asked?).to be false - end - - it 'does not send confirmation and notice emails' do - expect { request }.to_not change { ActionMailer::Base.deliveries.count } - end - end - - context 'when given registrant is different than current one' do - let!(:registrant) { create(:registrant, code: 'OLD-CODE') } - let!(:new_registrant) { create(:registrant, code: 'NEW-CODE') } - let(:request_xml) { <<-XML - - - - - - test.com - - NEW-CODE - - - - - - #{valid_legal_document} - - - - - XML - } - - specify do - request - expect(response).to have_code_of(1000) - end - - it 'changes registrant without confirmation' do - expect { request; domain.reload }.to change { domain.registrant.code }.from('OLD-CODE').to('NEW-CODE') - end - - it 'does not ask for confirmation' do - request - domain.reload - expect(domain.registrant_verification_asked?).to be false - end - - it 'does not set PENDING_UPDATE status' do - request - domain.reload - expect(domain.statuses).to_not include(DomainStatus::PENDING_UPDATE) - end - - it 'does not send confirmation and notice emails' do - expect { request }.to_not change { ActionMailer::Base.deliveries.count } - end - end - end -end diff --git a/spec/requests/epp/domain/update/registrant_change/verified_spec.rb b/spec/requests/epp/domain/update/registrant_change/verified_spec.rb deleted file mode 100644 index 5e0cee39d..000000000 --- a/spec/requests/epp/domain/update/registrant_change/verified_spec.rb +++ /dev/null @@ -1,199 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP domain:update' do - let(:registrar) { create(:registrar) } - let(:user) { create(:api_user_epp, registrar: registrar) } - let(:session_id) { create(:epp_session, user: user).session_id } - let(:request) { post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" } - let!(:registrant) { create(:registrant, code: 'old-code') } - let!(:domain) { create(:domain, name: 'test.com', registrant: registrant) } - let!(:new_registrant) { create(:registrant, code: 'new-code') } - - before :example do - sign_in user - end - - context 'when registrant change confirmation is enabled' do - before :example do - Setting.request_confrimation_on_registrant_change_enabled = true - end - - context 'when verified' do - let(:request_xml) { <<-XML - - - - - - test.com - - new-code - - - - - - #{valid_legal_document} - - - - - XML - } - - specify do - request - expect(response).to have_code_of(1000) - end - - it 'changes registrant' do - expect { request; domain.reload }.to change { domain.registrant.code }.from('old-code').to('new-code') - end - - it 'does not send confirmation email' do - expect { request }.to_not change { ActionMailer::Base.deliveries.count } - end - - it 'does not set PENDING_UPDATE status to domain' do - request - domain.reload - expect(domain.statuses).to_not include(DomainStatus::PENDING_UPDATE) - end - end - - context 'when not verified' do - let(:request_xml) { <<-XML - - - - - - test.com - - new-code - - - - - - #{valid_legal_document} - - - - - XML - } - - specify do - request - expect(response).to have_code_of(1001) - end - - it 'does not change registrant' do - expect { request; domain.reload }.to_not change { domain.registrant.code } - end - - it 'sends confirmation and notice emails' do - expect { request }.to change { ActionMailer::Base.deliveries.count }.by(2) - end - - it 'sets PENDING_UPDATE status to domain' do - request - domain.reload - expect(domain.statuses).to include(DomainStatus::PENDING_UPDATE) - end - end - end - - context 'when registrant change confirmation is disabled' do - before :example do - Setting.request_confrimation_on_registrant_change_enabled = false - end - - context 'when verified' do - let(:request_xml) { <<-XML - - - - - - test.com - - new-code - - - - - - #{valid_legal_document} - - - - - XML - } - - specify do - request - expect(response).to have_code_of(1000) - end - - it 'changes registrant' do - expect { request; domain.reload }.to change { domain.registrant.code }.from('old-code').to('new-code') - end - - it 'does not send confirmation email' do - expect { request }.to_not change { ActionMailer::Base.deliveries.count } - end - - it 'does not set PENDING_UPDATE status to domain' do - request - domain.reload - expect(domain.statuses).to_not include(DomainStatus::PENDING_UPDATE) - end - end - - context 'when not verified' do - let(:request_xml) { <<-XML - - - - - - test.com - - new-code - - - - - - #{valid_legal_document} - - - - - XML - } - - specify do - request - expect(response).to have_code_of(1000) - end - - it 'changes registrant' do - expect { request; domain.reload }.to change { domain.registrant.code }.from('old-code').to('new-code') - end - - it 'does not send confirmation email' do - expect { request }.to_not change { ActionMailer::Base.deliveries.count } - end - - it 'does not set PENDING_UPDATE status to domain' do - request - domain.reload - expect(domain.statuses).to_not include(DomainStatus::PENDING_UPDATE) - end - end - end -end diff --git a/spec/requests/epp/domain/update/status_spec.rb b/spec/requests/epp/domain/update/status_spec.rb deleted file mode 100644 index 19be7a960..000000000 --- a/spec/requests/epp/domain/update/status_spec.rb +++ /dev/null @@ -1,40 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP domain:update' do - let(:registrar) { create(:registrar) } - let(:user) { create(:api_user_epp, registrar: registrar) } - let(:session_id) { create(:epp_session, user: user).session_id } - let(:request) { post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" } - let(:request_xml) { <<-XML - - - - - - test.com - - - - - XML - } - - before :example do - sign_in user - end - - context 'when domain has both SERVER_DELETE_PROHIBITED and PENDING_UPDATE statuses' do - let!(:domain) { create(:domain, - name: 'test.com', - statuses: [DomainStatus::SERVER_DELETE_PROHIBITED, - DomainStatus::PENDING_UPDATE]) - } - - it 'returns PENDING_UPDATE as domain status' do - request - status = Nokogiri::XML(response.body).at_xpath('//domain:status', - domain: 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').content - expect(status).to eq(DomainStatus::PENDING_UPDATE) - end - end -end diff --git a/spec/requests/registrar/ip_restriction_spec.rb b/spec/requests/registrar/ip_restriction_spec.rb deleted file mode 100644 index 49a04428a..000000000 --- a/spec/requests/registrar/ip_restriction_spec.rb +++ /dev/null @@ -1,87 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'Registrar area IP restriction', settings: false do - before do - @original_registrar_ip_whitelist_enabled_setting = Setting.registrar_ip_whitelist_enabled - end - - after do - Setting.registrar_ip_whitelist_enabled = @original_registrar_ip_whitelist_enabled_setting - end - - context 'when authenticated' do - before do - sign_in_to_registrar_area - end - - context 'when IP restriction is enabled' do - before do - Setting.registrar_ip_whitelist_enabled = true - end - - context 'when ip is allowed' do - let!(:white_ip) { create(:white_ip, - ipv4: '127.0.0.1', - registrar: controller.current_registrar_user.registrar, - interfaces: [WhiteIp::REGISTRAR]) } - - specify do - get registrar_root_url - expect(response).to be_success - end - end - - context 'when ip is not allowed' do - it 'signs the user out' do - get registrar_root_url - expect(controller.current_registrar_user).to be_nil - end - - it 'redirects to login url' do - get registrar_root_url - expect(response).to redirect_to(new_registrar_user_session_url) - end - end - end - - context 'when IP restriction is disabled' do - specify do - get registrar_root_url - expect(response).to be_success - end - end - end - - context 'when unauthenticated' do - context 'when IP restriction is enabled' do - before do - Setting.registrar_ip_whitelist_enabled = true - end - - context 'when ip is allowed' do - let!(:white_ip) { create(:white_ip, - ipv4: '127.0.0.1', - interfaces: [WhiteIp::REGISTRAR]) } - - specify do - get new_registrar_user_session_path - expect(response).to be_success - end - end - - context 'when ip is not allowed' do - specify do - get new_registrar_user_session_path - expect(response.body).to match "Access denied" - end - end - end - - context 'when IP restriction is disabled' do - specify do - get new_registrar_user_session_path - expect(response).to be_success - end - end - end -end diff --git a/spec/requests/registrar/linked_users_spec.rb b/spec/requests/registrar/linked_users_spec.rb deleted file mode 100644 index 05cf10600..000000000 --- a/spec/requests/registrar/linked_users_spec.rb +++ /dev/null @@ -1,68 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'Registrar area linked users', db: false do - describe 'user switch' do - context 'when user is authenticated', db: true do - let!(:current_user) { create(:api_user, id: 1, identity_code: 'code') } - - before do - sign_in current_user - end - - context 'when ip is allowed' do - let(:restricted_ip) { instance_double(Authorization::RestrictedIP, - can_access_registrar_area?: true) } - - before do - allow(Authorization::RestrictedIP).to receive(:new).and_return(restricted_ip) - end - - context 'when new user is linked' do - let!(:new_user) { create(:api_user, id: 2, identity_code: 'code') } - - it 'signs in as a new user' do - put '/registrar/current_user/switch/2', nil, { HTTP_REFERER: registrar_contacts_url } - follow_redirect! - expect(controller.current_registrar_user.id).to eq(2) - end - - it 'redirects back' do - put '/registrar/current_user/switch/2', nil, { HTTP_REFERER: 'http://previous.url' } - expect(response).to redirect_to('http://previous.url') - end - end - - context 'when new user is unlinked' do - let!(:new_user) { create(:api_user, id: 2, identity_code: 'another-code') } - - it 'throws exception' do - expect do - put '/registrar/current_user/switch/2', nil, { HTTP_REFERER: registrar_contacts_path } - end.to raise_error('Cannot switch to unlinked user') - end - end - end - - context 'when ip is not allowed' do - let(:restricted_ip) { instance_double(Authorization::RestrictedIP, - can_access_registrar_area?: false) } - - before do - allow(Authorization::RestrictedIP).to receive(:new).and_return(restricted_ip) - end - - specify do - put '/registrar/current_user/switch/2' - expect(response).to redirect_to(new_registrar_user_session_url) - end - end - end - - context 'when user is not authenticated' do - specify do - put '/registrar/current_user/switch/2' - expect(response).to redirect_to(new_registrar_user_session_url) - end - end - end -end diff --git a/spec/routing/registrant/domain_delete_confirms_routing_spec.rb b/spec/routing/registrant/domain_delete_confirms_routing_spec.rb deleted file mode 100644 index cf7691bb4..000000000 --- a/spec/routing/registrant/domain_delete_confirms_routing_spec.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'rails_helper' - -RSpec.describe Registrant::DomainDeleteConfirmsController do - describe 'routing' do - it 'routes to #show' do - expect(get: '/registrant/domain_delete_confirms/1').to route_to('registrant/domain_delete_confirms#show', id: '1') - end - end -end diff --git a/spec/routing/registrant/domain_update_confirms_routing_spec.rb b/spec/routing/registrant/domain_update_confirms_routing_spec.rb deleted file mode 100644 index 9bc98c391..000000000 --- a/spec/routing/registrant/domain_update_confirms_routing_spec.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'rails_helper' - -RSpec.describe Registrant::DomainUpdateConfirmsController do - describe 'routing' do - it 'routes to #show' do - expect(get: '/registrant/domain_update_confirms/1').to route_to('registrant/domain_update_confirms#show', id: '1') - end - end -end diff --git a/spec/services/registrant_change_spec.rb b/spec/services/registrant_change_spec.rb deleted file mode 100644 index 598874109..000000000 --- a/spec/services/registrant_change_spec.rb +++ /dev/null @@ -1,20 +0,0 @@ -require 'rails_helper' - -RSpec.describe RegistrantChange do - describe '#confirm' do - let(:domain) { instance_double(Domain) } - let(:old_registrant) { instance_double(Registrant) } - let(:message) { instance_spy(ActionMailer::MessageDelivery) } - - before :example do - allow(RegistrantChangeMailer).to receive(:accepted) - .with(domain: domain, old_registrant: old_registrant) - .and_return(message) - described_class.new(domain: domain, old_registrant: old_registrant).confirm - end - - it 'notifies registrant' do - expect(message).to have_received(:deliver_now) - end - end -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb deleted file mode 100644 index f10463346..000000000 --- a/spec/spec_helper.rb +++ /dev/null @@ -1,76 +0,0 @@ -if ENV['COVERAGE'] - require 'simplecov' - SimpleCov.command_name 'spec' -end - -require 'webmock/rspec' -WebMock.disable_net_connect!(allow_localhost: true) - -RSpec.configure do |config| - # rspec-expectations config goes here. You can use an alternate - # assertion/expectation library such as wrong or the stdlib/minitest - # assertions if you prefer. - config.expect_with :rspec do |expectations| - # This option will default to `true` in RSpec 4. It makes the `description` - # and `failure_message` of custom matchers include text for helper methods - # defined using `chain`, e.g.: - # be_bigger_than(2).and_smaller_than(4).description - # # => "be bigger than 2 and smaller than 4" - # ...rather than: - # # => "be bigger than 2" - expectations.include_chain_clauses_in_custom_matcher_descriptions = true - end - - config.mock_with :rspec do |mocks| - mocks.verify_partial_doubles = true - end - - # The settings below are suggested to provide a good initial experience - # with RSpec, but feel free to customize to your heart's content. -=begin - # These two settings work together to allow you to limit a spec run - # to individual examples or groups you care about by tagging them with - # `:focus` metadata. When nothing is tagged with `:focus`, all examples - # get run. - config.filter_run :focus - config.run_all_when_everything_filtered = true - - # Limits the available syntax to the non-monkey patched syntax that is recommended. - # For more details, see: - # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax - # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ - # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching - config.disable_monkey_patching! - - # This setting enables warnings. It's recommended, but in some cases may - # be too noisy due to issues in dependencies. - config.warnings = true - - # Many RSpec users commonly either run the entire suite or an individual - # file, and it's useful to allow more verbose output when running an - # individual spec file. - if config.files_to_run.one? - # Use the documentation formatter for detailed output, - # unless a formatter has already been configured - # (e.g. via a command-line flag). - config.default_formatter = 'doc' - end - - # Print the 10 slowest examples and example groups at the - # end of the spec run, to help surface which specs are running - # particularly slow. - config.profile_examples = 10 - - # Run specs in random order to surface order dependencies. If you find an - # order dependency and want to debug it, you can fix the order by providing - # the seed, which is printed after each run. - # --seed 1234 - config.order = :random - - # Seed global randomization in this process using the `--seed` CLI option. - # Setting this allows you to use `--seed` to deterministically reproduce - # test failures related to randomization by passing the same `--seed` value - # as the one that triggered the failure. - Kernel.srand config.seed -=end -end diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb deleted file mode 100644 index 5434f1a84..000000000 --- a/spec/support/capybara.rb +++ /dev/null @@ -1,6 +0,0 @@ -require_relative 'macros/capybara' - -RSpec.configure do |config| - config.include CapybaraViewMacros, type: :view - config.include CapybaraViewMacros, type: :presenter -end diff --git a/spec/support/database_cleaner.rb b/spec/support/database_cleaner.rb deleted file mode 100644 index 581f5ac7c..000000000 --- a/spec/support/database_cleaner.rb +++ /dev/null @@ -1,30 +0,0 @@ -RSpec.configure do |config| - db_connection_names = ActiveRecord::Base.configurations.keys.grep(/test/).map(&:to_sym).reverse - - config.before :suite do - DatabaseCleaner.strategy = :truncation - - db_connection_names.each do |connection_name| - ActiveRecord::Base.establish_connection(connection_name) - DatabaseCleaner[:active_record, connection: connection_name].strategy = :truncation - end - end - - config.before :example do |example| - if example.metadata[:db] - db_connection_names.each do |connection_name| - ActiveRecord::Base.establish_connection(connection_name) - DatabaseCleaner[:active_record, connection: connection_name].start - end - end - end - - config.after :example do |example| - if example.metadata[:db] - db_connection_names.each do |connection_name| - ActiveRecord::Base.establish_connection(connection_name) - DatabaseCleaner[:active_record, connection: connection_name].clean - end - end - end -end diff --git a/spec/support/devise.rb b/spec/support/devise.rb deleted file mode 100644 index 4dcb76759..000000000 --- a/spec/support/devise.rb +++ /dev/null @@ -1,3 +0,0 @@ -RSpec.configure do |config| - config.include Warden::Test::Helpers -end diff --git a/spec/support/factory_bot.rb b/spec/support/factory_bot.rb deleted file mode 100644 index c7890e49c..000000000 --- a/spec/support/factory_bot.rb +++ /dev/null @@ -1,3 +0,0 @@ -RSpec.configure do |config| - config.include FactoryBot::Syntax::Methods -end diff --git a/spec/support/features/session_helpers.rb b/spec/support/features/session_helpers.rb deleted file mode 100644 index 11724f420..000000000 --- a/spec/support/features/session_helpers.rb +++ /dev/null @@ -1,26 +0,0 @@ -module Features - module SessionHelpers - def sign_in_to_admin_area(user: create(:admin_user)) - visit new_admin_user_session_url - - fill_in 'admin_user[username]', with: user.username - fill_in 'admin_user[password]', with: user.password - - click_button 'Sign in' - end - - def sign_in_to_registrar_area(user: create(:api_user)) - visit new_registrar_user_session_url - - fill_in 'registrar_user_username', with: user.username - fill_in 'registrar_user_password', with: user.plain_text_password - - click_button 'Login' - end - - def sign_in_to_registrant_area - user = create(:registrant_user) - sign_in(user, scope: :user) - end - end -end diff --git a/spec/support/macros/capybara.rb b/spec/support/macros/capybara.rb deleted file mode 100644 index 0e9dbf7b0..000000000 --- a/spec/support/macros/capybara.rb +++ /dev/null @@ -1,5 +0,0 @@ -module CapybaraViewMacros - def page - Capybara::Node::Simple.new(rendered) - end -end diff --git a/spec/support/matchers/alias_attribute.rb b/spec/support/matchers/alias_attribute.rb deleted file mode 100644 index 93b4efbb0..000000000 --- a/spec/support/matchers/alias_attribute.rb +++ /dev/null @@ -1,9 +0,0 @@ -RSpec::Matchers.define :alias_attribute do |alias_name, original_name| - match do |actual| - actual.class.attribute_alias(alias_name) == original_name.to_s - end - - failure_message do |actual| - "expected #{actual.class.name} to alias attribute :#{alias_name} by :#{original_name}" - end -end diff --git a/spec/support/matchers/epp/code.rb b/spec/support/matchers/epp/code.rb deleted file mode 100644 index 042598c50..000000000 --- a/spec/support/matchers/epp/code.rb +++ /dev/null @@ -1,39 +0,0 @@ -module Matchers - module EPP - class Code - def initialize(expected) - @expected = expected - end - - def matches?(response) - @xml = response.body - actual == expected - end - - def failure_message - "Expected EPP code of #{expected}, got #{actual} (#{code_description})" - end - - def description - "should have EPP code of #{expected}" - end - - private - - attr_reader :xml - attr_reader :expected - - def actual - xml_document.xpath('//xmlns:result').first['code'].to_i - end - - def code_description - xml_document.css('result msg').text - end - - def xml_document - @xml_document ||= Nokogiri::XML(xml) - end - end - end -end diff --git a/spec/support/matchers/epp/have_result.rb b/spec/support/matchers/epp/have_result.rb deleted file mode 100644 index 7850082dd..000000000 --- a/spec/support/matchers/epp/have_result.rb +++ /dev/null @@ -1,37 +0,0 @@ -module Matchers - module EPP - class HaveResultMatcher - def initialize(expected) - @expected = expected - end - - def matches?(target) - @target = target - - if @expected.message.present? - @target.results.any? { |result| result.code == @expected.code && result.message == @expected.message } - else - @target.results.any? { |result| result.code == @expected.code } - end - end - - def failure_message - "expected #{@target.results} to have result #{@expected.inspect}" - end - - def failure_message_when_negated - "expected #{@target.results} not to have result #{@expected.inspect}" - end - - def description - "should have EPP code of #{@expected}" - end - end - - def have_result(type, message = nil) - code = ::EPP::Response::Result.codes.key(type) - result = ::EPP::Response::Result.new(code, message) - HaveResultMatcher.new(result) - end - end -end diff --git a/spec/support/paper_trail.rb b/spec/support/paper_trail.rb deleted file mode 100644 index 7304b8b60..000000000 --- a/spec/support/paper_trail.rb +++ /dev/null @@ -1 +0,0 @@ -PaperTrail.whodunnit = 'autotest' diff --git a/spec/support/requests/epp_helpers.rb b/spec/support/requests/epp_helpers.rb deleted file mode 100644 index fb0175df1..000000000 --- a/spec/support/requests/epp_helpers.rb +++ /dev/null @@ -1,15 +0,0 @@ -module Requests - module EPPHelpers - def have_code_of(*args) - Matchers::EPP::Code.new(*args) - end - - def valid_legal_document - Base64.encode64('a' * 5000) - end - - def epp_response - EPP::Response.from_xml(response.body) - end - end -end diff --git a/spec/support/requests/session_helpers.rb b/spec/support/requests/session_helpers.rb deleted file mode 100644 index 1a7b90138..000000000 --- a/spec/support/requests/session_helpers.rb +++ /dev/null @@ -1,11 +0,0 @@ -module Requests - module SessionHelpers - def sign_in_to_admin_area(user: create(:admin_user)) - post admin_user_session_path, admin_user: { username: user.username, password: user.password } - end - - def sign_in_to_registrar_area(user: create(:api_user)) - post registrar_user_session_path, { registrar_user: { username: user.username, password: user.plain_text_password } } - end - end -end \ No newline at end of file diff --git a/spec/support/settings.rb b/spec/support/settings.rb deleted file mode 100644 index e39fea035..000000000 --- a/spec/support/settings.rb +++ /dev/null @@ -1,28 +0,0 @@ -RSpec.configure do |config| - config.before :example do |example| - if example.metadata[:db] && (example.metadata[:settings] != false) - create(:zone, origin: 'com') - - Setting.ds_algorithm = 2 - Setting.ds_data_allowed = true - Setting.ds_data_with_key_allowed = true - Setting.key_data_allowed = false - - Setting.dnskeys_min_count = 0 - Setting.dnskeys_max_count = 9 - - Setting.nameserver_required = false - Setting.ns_min_count = 2 - Setting.ns_max_count = 11 - - Setting.transfer_wait_time = 0 - - Setting.admin_contacts_min_count = 1 - Setting.admin_contacts_max_count = 10 - Setting.tech_contacts_min_count = 0 - Setting.tech_contacts_max_count = 10 - - Setting.client_side_status_editing_enabled = true - end - end -end diff --git a/spec/validators/contact/ident/mismatch_validator_spec.rb b/spec/validators/contact/ident/mismatch_validator_spec.rb deleted file mode 100644 index dfb30fe09..000000000 --- a/spec/validators/contact/ident/mismatch_validator_spec.rb +++ /dev/null @@ -1,13 +0,0 @@ -require 'rails_helper' - -RSpec.describe Contact::Ident::MismatchValidator do - describe '::mismatches' do - it 'returns mismatches' do - mismatches = [ - Contact::Ident::MismatchValidator::Mismatch.new('birthday', Country.new('EE')) - ] - - expect(described_class.mismatches).to eq(mismatches) - end - end -end diff --git a/spec/views/admin/billing/prices/_form.html.erb_spec.rb b/spec/views/admin/billing/prices/_form.html.erb_spec.rb deleted file mode 100644 index 2349a5d1e..000000000 --- a/spec/views/admin/billing/prices/_form.html.erb_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'rails_helper' -require 'views/shared_examples/money_form_field' - -RSpec.describe 'admin/billing/prices/_form' do - let(:price) { build_stubbed(:price) } - - before :example do - without_partial_double_verification do - allow(view).to receive(:price).and_return(price) - allow(view).to receive(:zones).and_return([]) - allow(view).to receive(:operation_categories).and_return([]) - allow(view).to receive(:durations).and_return([]) - end - - stub_template '_form_errors.html.erb' => '' - end - - describe 'price' do - let(:field) { page.find('#price_price') } - it_behaves_like 'money form field' - end -end diff --git a/spec/views/admin/dns/zones/index.html.erb_spec.rb b/spec/views/admin/dns/zones/index.html.erb_spec.rb deleted file mode 100644 index e066ce79b..000000000 --- a/spec/views/admin/dns/zones/index.html.erb_spec.rb +++ /dev/null @@ -1,40 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'admin/dns/zones/index' do - let(:zones) { [] } - - before :example do - assign(:zones, zones) - stub_template '_zone.html.erb' => 'zone-row' - end - - it 'has title' do - render - expect(rendered).to have_text(t('admin.dns.zones.index.title')) - end - - context 'when zones are present' do - let(:zones) { [build_stubbed(:zone)] } - - it 'has zone row' do - render - expect(rendered).to have_text('zone-row') - end - - it 'has no :not_found message' do - render - expect(rendered).to_not have_text(not_found_message) - end - end - - context 'when zones are absent' do - it 'has :not_found message' do - render - expect(rendered).to have_text(not_found_message) - end - end - - def not_found_message - t('admin.dns.zones.index.not_found') - end -end diff --git a/spec/views/admin/domains/edit.html.erb_spec.rb b/spec/views/admin/domains/edit.html.erb_spec.rb deleted file mode 100644 index 3f74a1f2e..000000000 --- a/spec/views/admin/domains/edit.html.erb_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'admin/domains/edit' do - let(:domain) { build_stubbed(:domain) } - let(:domain_presenter) { DomainPresenter.new(domain: domain, view: view) } - - before :example do - allow(DomainPresenter).to receive(:new).and_return(domain_presenter) - - without_partial_double_verification do - allow(view).to receive(:force_delete_templates) - end - - assign(:domain, domain) - - stub_template '_form.html.erb' => '' - stub_template '_force_delete_dialog.html.erb' => '' - end - - it 'has force_delete_toggle_btn' do - expect(domain_presenter).to receive(:force_delete_toggle_btn).and_return('force_delete_toggle_btn') - render - expect(rendered).to have_content('force_delete_toggle_btn') - end -end diff --git a/spec/views/registrar/contacts/_form.haml_spec.rb b/spec/views/registrar/contacts/_form.haml_spec.rb deleted file mode 100644 index 4feead879..000000000 --- a/spec/views/registrar/contacts/_form.haml_spec.rb +++ /dev/null @@ -1,45 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'registrar/contacts/_form' do - let(:contact) { instance_spy(Depp::Contact) } - - before :example do - without_partial_double_verification do - allow(view).to receive(:f).and_return(ActionView::Helpers::FormBuilder.new(:contact, contact, view, {})) - end - - assign(:contact, contact) - - stub_template 'registrar/shared/_error_messages.haml' => '' - stub_template 'registrar/contacts/form/_general.html.haml' => '' - stub_template 'registrar/contacts/form/_address.html.haml' => 'address info' - stub_template 'registrar/contacts/form/_code.html.haml' => '' - stub_template 'registrar/contacts/form/_legal_document.html.haml' => '' - end - - context 'when address processing is enabled' do - before do - without_partial_double_verification do - allow(view).to receive(:address_processing?).and_return(true) - end - end - - it 'has address' do - render - expect(rendered).to have_text('address info') - end - end - - context 'when address processing is disabled' do - before do - without_partial_double_verification do - allow(view).to receive(:address_processing?).and_return(false) - end - end - - it 'has no address' do - render - expect(rendered).to_not have_text('address info') - end - end -end diff --git a/spec/views/registrar/contacts/form/_legal_document.haml_spec.rb b/spec/views/registrar/contacts/form/_legal_document.haml_spec.rb deleted file mode 100644 index 55ac79e9e..000000000 --- a/spec/views/registrar/contacts/form/_legal_document.haml_spec.rb +++ /dev/null @@ -1,18 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'registrar/contacts/form/_legal_document' do - let(:contact) { instance_spy(Depp::Contact) } - - before :example do - without_partial_double_verification do - allow(view).to receive(:f).and_return(DefaultFormBuilder.new(:depp_contact, contact, view, {})) - end - - assign(:contact, contact) - end - - it 'has legal document' do - render - expect(rendered).to have_css('[name="depp_contact[legal_document]"]') - end -end diff --git a/spec/views/registrar/contacts/show.haml_spec.rb b/spec/views/registrar/contacts/show.haml_spec.rb deleted file mode 100644 index 666d151ff..000000000 --- a/spec/views/registrar/contacts/show.haml_spec.rb +++ /dev/null @@ -1,36 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'registrar/contacts/show' do - let(:contact) { instance_spy(Depp::Contact, id: 1, name: 'test') } - - before do - assign(:contact, contact) - stub_template 'shared/_title.html.haml' => '' - stub_template 'registrar/contacts/partials/_general.html.haml' => '' - stub_template 'registrar/contacts/partials/_statuses.html.haml' => '' - stub_template 'registrar/contacts/partials/_domains.html.haml' => '' - stub_template 'registrar/contacts/partials/_address.html.haml' => 'address info' - end - - context 'when address processing is enabled' do - before do - allow(Contact).to receive(:address_processing?).and_return(true) - end - - it 'has address' do - render - expect(rendered).to have_text('address info') - end - end - - context 'when address processing is disabled' do - before do - allow(Contact).to receive(:address_processing?).and_return(false) - end - - it 'has no address' do - render - expect(rendered).to_not have_text('address info') - end - end -end diff --git a/spec/views/registrar/domains/_form.haml_spec.rb b/spec/views/registrar/domains/_form.haml_spec.rb deleted file mode 100644 index 723ab081b..000000000 --- a/spec/views/registrar/domains/_form.haml_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'registrar/domains/_form' do - let(:domain) { instance_spy(Depp::Domain) } - - before :example do - without_partial_double_verification do - allow(view).to receive(:f).and_return(DefaultFormBuilder.new(:domain, domain, view, {})) - end - - assign(:domain, domain) - - stub_template 'registrar/domains/form/_general.html.haml' => '' - stub_template 'registrar/domains/form/_contacts.html.haml' => '' - stub_template 'registrar/domains/form/_nameservers.html.haml' => '' - stub_template 'registrar/domains/form/_dnskeys.html.haml' => '' - end - - it 'has legal document' do - render - expect(rendered).to have_css('[name="domain[legal_document]"]') - end -end diff --git a/spec/views/shared_examples/money_form_field.rb b/spec/views/shared_examples/money_form_field.rb deleted file mode 100644 index e169f5127..000000000 --- a/spec/views/shared_examples/money_form_field.rb +++ /dev/null @@ -1,11 +0,0 @@ -RSpec.shared_examples 'money form field' do - it 'has max length' do - render - expect(field[:maxlength]).to eq('255') - end - - it 'has money pattern' do - render - expect(field[:pattern]).to eq('^[0-9.,]+$') - end -end diff --git a/test/application_system_test_case.rb b/test/application_system_test_case.rb index cceeb27c5..b31489691 100644 --- a/test/application_system_test_case.rb +++ b/test/application_system_test_case.rb @@ -3,13 +3,24 @@ require 'test_helper' require 'database_cleaner' require 'selenium/webdriver' -ApplicationSystemTestCase = Class.new(ApplicationIntegrationTest) +class ApplicationSystemTestCase < ActionDispatch::IntegrationTest + include Capybara::DSL + include Capybara::Minitest::Assertions + include AbstractController::Translation + include Devise::Test::IntegrationHelpers + + teardown do + WebMock.reset! + Capybara.reset_sessions! + Capybara.use_default_driver + end +end class JavaScriptApplicationSystemTestCase < ApplicationSystemTestCase - self.use_transactional_fixtures = false + self.use_transactional_tests = false DatabaseCleaner.strategy = :truncation - Capybara.register_driver(:chrome) do |_app| + Capybara.register_driver(:chrome) do |app| options = ::Selenium::WebDriver::Chrome::Options.new options.add_argument('--headless') @@ -17,13 +28,10 @@ class JavaScriptApplicationSystemTestCase < ApplicationSystemTestCase options.add_argument('--disable-dev-shm-usage') options.add_argument('--window-size=1400,1400') - Capybara::Selenium::Driver.new(Rails.application, browser: :chrome, options: options) + Capybara::Selenium::Driver.new(app, browser: :chrome, options: options) end - Capybara.register_server(:silent_puma) do |app, port, _host| - require 'rack/handler/puma' - Rack::Handler::Puma.run(app, Port: port, Threads: '0:2', Silent: true) - end + Capybara.server = :puma, { Silent: true } def setup DatabaseCleaner.start @@ -31,7 +39,6 @@ class JavaScriptApplicationSystemTestCase < ApplicationSystemTestCase super Capybara.current_driver = :chrome - Capybara.server = :silent_puma end def teardown diff --git a/test/fixtures/account_activities.yml b/test/fixtures/account_activities.yml index dbe1dc2aa..8f883e424 100644 --- a/test/fixtures/account_activities.yml +++ b/test/fixtures/account_activities.yml @@ -2,4 +2,4 @@ one: account: cash invoice: one bank_transaction: one - created_at: <%= Time.zone.parse('2010-07-05 10:00') %> \ No newline at end of file + created_at: <%= Time.zone.parse('2010-07-05 10:00') %> diff --git a/test/fixtures/bank_transactions.yml b/test/fixtures/bank_transactions.yml index ada80981d..70b3b6651 100644 --- a/test/fixtures/bank_transactions.yml +++ b/test/fixtures/bank_transactions.yml @@ -1,5 +1,5 @@ one: sum: 1 currency: EUR - description: Order nr. 1 - iban: US75512108001245126199 \ No newline at end of file + description: Order nr 1 from registrar 1234567 second number 2345678 + iban: US75512108001245126199 diff --git a/test/fixtures/billing/prices.yml b/test/fixtures/billing/prices.yml index 2237a72b4..24aa9f980 100644 --- a/test/fixtures/billing/prices.yml +++ b/test/fixtures/billing/prices.yml @@ -1,5 +1,5 @@ create_one_month: - duration: 1 month + duration: 3 mons price_cents: 100 operation_category: create valid_from: 2010-07-05 @@ -7,7 +7,7 @@ create_one_month: zone: one renew_one_month: - duration: 1 month + duration: 1 mons price_cents: 100 operation_category: renew valid_from: 2010-07-05 diff --git a/test/fixtures/blocked_domains.yml b/test/fixtures/blocked_domains.yml index 4bf0d0299..52c9beec2 100644 --- a/test/fixtures/blocked_domains.yml +++ b/test/fixtures/blocked_domains.yml @@ -1,2 +1,4 @@ one: name: blocked.test +idn: + name: blockedäöüõ.test diff --git a/test/fixtures/certificates.yml b/test/fixtures/certificates.yml new file mode 100644 index 000000000..4799743ff --- /dev/null +++ b/test/fixtures/certificates.yml @@ -0,0 +1,14 @@ +api: + api_user: api_bestnames + common_name: registry.test + crt: "-----BEGIN CERTIFICATE-----\nMIICYjCCAcugAwIBAgIBADANBgkqhkiG9w0BAQ0FADBNMQswCQYDVQQGEwJ1czEO\nMAwGA1UECAwFVGV4YXMxFjAUBgNVBAoMDVJlZ2lzdHJ5IHRlc3QxFjAUBgNVBAMM\nDXJlZ2lzdHJ5LnRlc3QwIBcNMjAwNTA1MTIzNzQxWhgPMjEyMDA0MTExMjM3NDFa\nME0xCzAJBgNVBAYTAnVzMQ4wDAYDVQQIDAVUZXhhczEWMBQGA1UECgwNUmVnaXN0\ncnkgdGVzdDEWMBQGA1UEAwwNcmVnaXN0cnkudGVzdDCBnzANBgkqhkiG9w0BAQEF\nAAOBjQAwgYkCgYEAyn+GCkUJIhdXVBOPrZH+Zj2B/tQfL5TLZwVYZQt38x6GQT+4\n6ndty467IJvKSUlHej7uMpsCzC8Ffmda4cZm16jO1vUb4hXIrmeKP84zLrrUpKag\ngZR4rBDbG2+uL4SzMyy3yeQysYuTiQ4N1i4vdhvkKYPSWIht/QFvuzdFq+0CAwEA\nAaNQME4wHQYDVR0OBBYEFD6B5j6NnMCDBnfbtjBYKBJM7sCRMB8GA1UdIwQYMBaA\nFD6B5j6NnMCDBnfbtjBYKBJM7sCRMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEN\nBQADgYEArtCR6VOabD3nM/KlZTmHMZVT4ntenYlNTM9FS0RatzPmdh4REhykvmZs\nOlBcpoV5tN5Y8bHOVRqY9V2e903QEhQgoccQhbt0Py6uFwfLv+WLKAUbeGnPqK9d\ndL3wXN9BQs0hJA6IZNFyz2F/gSTURrD1zWW2na3ipRzhupW5+98=\n-----END CERTIFICATE-----\n" + md5: e6771ed5dc857a1dbcc1e0a36baa1fee + interface: api + revoked: false +registrar: + api_user: api_bestnames + common_name: registry.test + crt: "-----BEGIN CERTIFICATE-----\nMIICYjCCAcugAwIBAgIBADANBgkqhkiG9w0BAQ0FADBNMQswCQYDVQQGEwJ1czEO\nMAwGA1UECAwFVGV4YXMxFjAUBgNVBAoMDVJlZ2lzdHJ5IHRlc3QxFjAUBgNVBAMM\nDXJlZ2lzdHJ5LnRlc3QwIBcNMjAwNTA1MTIzNzQxWhgPMjEyMDA0MTExMjM3NDFa\nME0xCzAJBgNVBAYTAnVzMQ4wDAYDVQQIDAVUZXhhczEWMBQGA1UECgwNUmVnaXN0\ncnkgdGVzdDEWMBQGA1UEAwwNcmVnaXN0cnkudGVzdDCBnzANBgkqhkiG9w0BAQEF\nAAOBjQAwgYkCgYEAyn+GCkUJIhdXVBOPrZH+Zj2B/tQfL5TLZwVYZQt38x6GQT+4\n6ndty467IJvKSUlHej7uMpsCzC8Ffmda4cZm16jO1vUb4hXIrmeKP84zLrrUpKag\ngZR4rBDbG2+uL4SzMyy3yeQysYuTiQ4N1i4vdhvkKYPSWIht/QFvuzdFq+0CAwEA\nAaNQME4wHQYDVR0OBBYEFD6B5j6NnMCDBnfbtjBYKBJM7sCRMB8GA1UdIwQYMBaA\nFD6B5j6NnMCDBnfbtjBYKBJM7sCRMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEN\nBQADgYEArtCR6VOabD3nM/KlZTmHMZVT4ntenYlNTM9FS0RatzPmdh4REhykvmZs\nOlBcpoV5tN5Y8bHOVRqY9V2e903QEhQgoccQhbt0Py6uFwfLv+WLKAUbeGnPqK9d\ndL3wXN9BQs0hJA6IZNFyz2F/gSTURrD1zWW2na3ipRzhupW5+98=\n-----END CERTIFICATE-----\n" + md5: e6771ed5dc857a1dbcc1e0a36baa1fee + interface: registrar + revoked: false diff --git a/test/fixtures/contacts.yml b/test/fixtures/contacts.yml index ddfbfe93f..0173d56dd 100644 --- a/test/fixtures/contacts.yml +++ b/test/fixtures/contacts.yml @@ -85,3 +85,11 @@ invalid: auth_info: any registrar: bestnames uuid: bd80c0f9-26ee-49e0-a2cb-2311d931c433 + +invalid_email: + name: any + code: invalid_email + email: invalid@invalid. + auth_info: any + registrar: bestnames + uuid: fa8c4f51-a221-4628-b3c6-47995f4edea3 diff --git a/test/fixtures/disputes.yml b/test/fixtures/disputes.yml new file mode 100644 index 000000000..222897ecc --- /dev/null +++ b/test/fixtures/disputes.yml @@ -0,0 +1,22 @@ +active: + domain_name: active-dispute.test + password: active-001 + starts_at: <%= Date.parse '2010-07-05' %> + expires_at: <%= Date.parse '2013-07-05' %> +future: + domain_name: future-dispute.test + password: active-001 + starts_at: <%= Date.parse '2010-10-05' %> + expires_at: <%= Date.parse '2013-10-05' %> +expired: + domain_name: shop.test + password: active-001 + starts_at: <%= Date.parse '2010-07-05' %> + expires_at: <%= Date.parse '2013-07-05' %> + closed: <%= Date.parse '2013-07-05' %> +closed: + domain_name: closed_dispute.test + password: active-001 + starts_at: <%= Date.parse '2010-07-05' %> + expires_at: <%= Date.parse '2013-07-05' %> + closed: <%= Date.parse '2013-07-05' %> diff --git a/test/fixtures/dns/zones.yml b/test/fixtures/dns/zones.yml index b826c9ef4..4f493a149 100644 --- a/test/fixtures/dns/zones.yml +++ b/test/fixtures/dns/zones.yml @@ -2,3 +2,10 @@ one: origin: test + ttl: 1 + refresh: 1 + retry: 1 + expire: 1 + minimum_ttl: 1 + email: admin@registry.test + master_nameserver: ns.test diff --git a/test/fixtures/domains.yml b/test/fixtures/domains.yml index bbf5ced40..87059e68a 100644 --- a/test/fixtures/domains.yml +++ b/test/fixtures/domains.yml @@ -1,5 +1,6 @@ shop: name: shop.test + name_puny: shop.test name_dirty: shop.test registrar: bestnames registrant: john @@ -15,6 +16,7 @@ shop: airport: name: airport.test + name_puny: airport.test name_dirty: airport.test registrar: bestnames registrant: john @@ -26,6 +28,7 @@ airport: library: name: library.test + name_puny: library.test name_dirty: library.test registrar: bestnames registrant: acme_ltd @@ -37,6 +40,7 @@ library: metro: name: metro.test + name_puny: metro.test name_dirty: metro.test registrar: goodnames registrant: jack @@ -48,6 +52,7 @@ metro: hospital: name: hospital.test + name_puny: hospital.test name_dirty: hospital.test registrar: goodnames registrant: john @@ -59,6 +64,8 @@ hospital: invalid: name: invalid.test + name_puny: invalid.test + name_dirty: invalid.test transfer_code: 1438d6 valid_to: <%= Time.zone.parse('2010-07-05').utc.to_s(:db) %> registrar: bestnames diff --git a/test/fixtures/files/bank_statement_test.txt b/test/fixtures/files/bank_statement_test.txt new file mode 100644 index 000000000..2b00fdc88 --- /dev/null +++ b/test/fixtures/files/bank_statement_test.txt @@ -0,0 +1,6 @@ +VV 000689EE4567890123456789012005181404 +VV 220200518 M EE456789012345678901EUR Algsaldo C 0 +VV 12020051847406380MK EE456789012345678901EUR689EE123456789012345678 Registripidaja 413 ettemaks C 5000 +VV 12020051847406461MK EE456789012345678901EUR767EE012345678901234567 Hankija 303 Kulu D 5000 +VV 320200518 M EE456789012345678901EUR Lõppsaldo C 0 +VV 999 10000 diff --git a/test/fixtures/files/keystore.p12 b/test/fixtures/files/keystore.p12 new file mode 100644 index 000000000..962ddede2 Binary files /dev/null and b/test/fixtures/files/keystore.p12 differ diff --git a/test/fixtures/files/legaldoc.pdf b/test/fixtures/files/legaldoc.pdf new file mode 100644 index 000000000..1ddf7a0e8 Binary files /dev/null and b/test/fixtures/files/legaldoc.pdf differ diff --git a/test/fixtures/files/test_ca/certs/ca.crt.pem b/test/fixtures/files/test_ca/certs/ca.crt.pem new file mode 100644 index 000000000..f03e09f52 --- /dev/null +++ b/test/fixtures/files/test_ca/certs/ca.crt.pem @@ -0,0 +1,35 @@ +-----BEGIN CERTIFICATE----- +MIIGDDCCA/SgAwIBAgIJAKaLNUIy97o1MA0GCSqGSIb3DQEBCwUAMIGVMQswCQYD +VQQGEwJFRTERMA8GA1UECAwISGFyanVtYWExEDAOBgNVBAcMB1RhbGxpbm4xIzAh +BgNVBAoMGkVlc3RpIEludGVybmV0aSBTaWh0YXN1dHVzMRowGAYDVQQDDBFlcHBf +cHJveHkgdGVzdCBjYTEgMB4GCSqGSIb3DQEJARYRaGVsbG9AaW50ZXJuZXQuZWUw +HhcNMTkwNzExMTMwMDEzWhcNMjAwNzEwMTMwMDEzWjCBlTELMAkGA1UEBhMCRUUx +ETAPBgNVBAgMCEhhcmp1bWFhMRAwDgYDVQQHDAdUYWxsaW5uMSMwIQYDVQQKDBpF +ZXN0aSBJbnRlcm5ldGkgU2lodGFzdXR1czEaMBgGA1UEAwwRZXBwX3Byb3h5IHRl +c3QgY2ExIDAeBgkqhkiG9w0BCQEWEWhlbGxvQGludGVybmV0LmVlMIICIjANBgkq +hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0PBwqZUeXZaR3mk3VTm7S78Xs4WDCfyi +RocHDU7cWhrBvFD5ZXzmbUJPPJHmljYAOLWLEyMzw0bvYVz2FSOCkBerxGFA4T17 +RhjDEAmMMWiBAoFj6tNmxj3bq7nZfwaOY6KIxGiZcqx4usOQ3tQ+cxvrqzFVyX24 +KScmx4l2HlmJu2boF8/C4LSYvGPys+2WKXlLr73gL+cmM7Z2Y+mNgURCKT9ODpFp +VdX9iTpmnF0UFmYq/cN8QFSNv0ErsMFDZWxAnDoy6gZzsUz3ZnznOdjB96PFV9aA +Rm5BYr7jMhu7rJPOyQNd9SfD6QhlyCSjd68p6nMFvYLG5lL5QxJSTotr3VuH1uqJ +kfFwlMPJZAj/SmFUnoIvWGCyujqx6ajVX8zBvmcalSp35LyDDCnlohorUuP9TNrI +U+k/Ap6vxfxSSIOPhq6BoFxMYASp8jo+8HdFOWce5krQh/h3vvEhu015yEXH4Vgb +6lL+nvUex35He1IQFERvRSj5IB1Yw6HpwYb7LIfjXYsfas3FuSxXz9Geb23dybYd +2MlmKeGvTyjM60BNW2ZKKQ00KgnqR62bPALbDZ/AnkzxnLd7NLVqKiSBzOOkZfaO +V7hDD78VzSklA2cSV1qaBPHUW4AgQkmDJIF/1H/K9nN/F6OWKSJ0Ug3XGwDjY3Ry +X//K+E1UNWMCAwEAAaNdMFswHQYDVR0OBBYEFP135kpzvaU8ZbO5z7UVlVkIZGgQ +MB8GA1UdIwQYMBaAFP135kpzvaU8ZbO5z7UVlVkIZGgQMAwGA1UdEwQFMAMBAf8w +CwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQDF3s887Qj2eLeJln1Z/Nem +ZR2tj0PvYEHEYKq9R8N8IM1ooZt475MgyYo7XDPcuG3MMaGY9WdjqoXlWSM7T518 +U9ajFLqwNEnlfjZ33SdVDskfoRsKiDKUlvTNngn19KtAp3SBmQS6fgghlgha3tb+ +W1fOgzCRwaVG4XcQfR+wijSSovFOp+5CY/FL6XUwtFCz4ZwnHgXciG91SjhEPB+J +P8iHFr4f0qV4kKv0hPfjQ7tneeho0AzI4BXOgbRJmur6+SP/gmsgBeKr1sUHuD+d +nIAlz4T2reV8FujcW3u8yT4PFIhi0mdnXKC6xKDFlmD9AQa7eUO1DHJiSZ7zAsLS +drsqMu3GhM70Uw0Oqv2aInv8N4vwF6CJ6p/wEUXTVjkjH3U/ZzuOGcl1/5sAao0r +APwRazSMcqrjc+JicpFZ6NGTwTs0G6KD0dqhhqoyoZzB/1UDR2cG5SsgSTqBUeGb +0VMW4EYU+DG1HV+OdNrFA0RgDn5o0VF3LxwAs5ErItlojFPeBDYMJvPGsMEarNHN +03JeeEK081gzLJQzFPQV1n6kE6CiGGTx4X3ptUtvvQBD/u6KNUwN5b6p5jOQBEdZ +F4PJOVZePI/dBHr98/jlcHfCOmySc+7uzPhB86OtdF/yYabImpvQ0cypZkXwzL6l +VgOJJfHQrIhSmCRVxCEJoQ== +-----END CERTIFICATE----- diff --git a/test/fixtures/files/test_ca/certs/ca.srl b/test/fixtures/files/test_ca/certs/ca.srl new file mode 100644 index 000000000..7c1fd1b47 --- /dev/null +++ b/test/fixtures/files/test_ca/certs/ca.srl @@ -0,0 +1 @@ +8728BF086E9B1CE5 diff --git a/test/fixtures/files/test_ca/crl/crl.pem b/test/fixtures/files/test_ca/crl/crl.pem new file mode 100644 index 000000000..e0e265c99 --- /dev/null +++ b/test/fixtures/files/test_ca/crl/crl.pem @@ -0,0 +1,22 @@ +-----BEGIN X509 CRL----- +MIIDkjCCAXoCAQEwDQYJKoZIhvcNAQELBQAwgZUxCzAJBgNVBAYTAkVFMREwDwYD +VQQIDAhIYXJqdW1hYTEQMA4GA1UEBwwHVGFsbGlubjEjMCEGA1UECgwaRWVzdGkg +SW50ZXJuZXRpIFNpaHRhc3V0dXMxGjAYBgNVBAMMEWVwcF9wcm94eSB0ZXN0IGNh +MSAwHgYJKoZIhvcNAQkBFhFoZWxsb0BpbnRlcm5ldC5lZRcNMTkwNzI5MDc1NTA5 +WhcNMjkwNzI2MDc1NTA5WjB+MBMCAhACFw0xOTA1MjkwNjM5MTJaMBMCAhADFw0x +OTA1MjkwODQxMDJaMBMCAhAEFw0xOTA1MzExMTI0NTJaMBMCAhAFFw0xOTA1MzEx +MTQyMjJaMBMCAhAGFw0xOTA1MzExMjQzNDlaMBMCAhAHFw0xOTA3MjkwNzU0MzRa +oDAwLjAfBgNVHSMEGDAWgBT9d+ZKc72lPGWzuc+1FZVZCGRoEDALBgNVHRQEBAIC +EAkwDQYJKoZIhvcNAQELBQADggIBAEk9pyZjqyYUdnA0Sv7RyevRUQGKbbf3EXdv +JLDyvI9rpoyuWPkMT6vPsYght0cf/wO7oaEK/uustvFEYQiJss60jI0XuczWypk9 +paKu3LhIy6Drm3locY2k0ESrgP9IwNzS5Xr0FiaWRIozbkcawte8M4Nqe8BO5prk +/5sLjv3eFnD7E445tZhu3vmXkD50FT3PLHVBEz4yS6Fx6nTiv+9QUu8NGf+bc6+o +YKPMy6Lh/wGC7p6sZJCOCjfzLAcqWfB2EW6XU8WeQcQCZ0au7zvZjQownCS9CeJV +KVsC4QiUt97FxR2gcEN2GJesywIF11X9o8s1K/Hz3+rrtU1ymoMLeumaRW24z35A +zVsdNwRfSPmt1qHlyaJaFhKG6jw5/nws+/wGFycIjWK0DSORiGCYdKD0cCjKJbNO +2QJnJlNOaCUUj8ULyiFOtZvdadc4JVW42NI/F+AFy/bnBK0uH6CenK5XwX3kEMme +KD8b5reUcVRhQdVJdAABFJlihIg05yENI7hlH1CKfy4vmlBKl+M2mW9cmNO8O6uS +KMH8/wLuLga9gYziNT1RmVNFbnpF0hc6CFtSnlVXXTlU/TrxheH8ykrHQhKEkQj+ +3krObDFDCUMKmaGu2nxRYZwLXzUe3wVl1SAxw0eEGyON/N83sLYlcrwWTVzRG3Z7 +RqRHPn+h +-----END X509 CRL----- diff --git a/test/fixtures/files/test_ca/crlnumber b/test/fixtures/files/test_ca/crlnumber new file mode 100644 index 000000000..83b33d238 --- /dev/null +++ b/test/fixtures/files/test_ca/crlnumber @@ -0,0 +1 @@ +1000 diff --git a/test/fixtures/files/test_ca/generate_certificates.sh b/test/fixtures/files/test_ca/generate_certificates.sh new file mode 100755 index 000000000..753b39ec3 --- /dev/null +++ b/test/fixtures/files/test_ca/generate_certificates.sh @@ -0,0 +1,15 @@ +# !/bin/sh +# Use localhost as common name. +openssl genrsa -out private/client.key.pem 4096 +openssl req -sha256 -config openssl.cnf -new -days 3650 -key private/client.key.pem -out csrs/client.csr.pem +openssl ca -config openssl.cnf -keyfile private/ca.key.pem -cert certs/ca.crt.pem -extensions usr_cert -notext -md sha256 -in csrs/client.csr.pem -days 3650 -out certs/client.crt.pem + +openssl genrsa -out private/revoked.key.pem 4096 +openssl req -sha256 -config openssl.cnf -new -days 3650 -key private/revoked.key.pem -out csrs/revoked.csr.pem +openssl ca -config openssl.cnf -keyfile private/ca.key.pem -cert certs/ca.crt.pem -extensions usr_cert -notext -md sha256 -in csrs/revoked.csr.pem -days 3650 -out certs/revoked.crt.pem +openssl ca -config openssl.cnf -keyfile private/ca.key.pem -cert certs/ca.crt.pem -revoke certs/revoked.crt.pem + +openssl ca -config openssl.cnf -keyfile private/ca.key.pem -cert certs/ca.crt.pem -crldays 3650 -gencrl -out crl/crl.pem + +openssl req -config openssl.cnf -new -sha256 -nodes -out server.csr -newkey rsa:2048 -keyout private/apache.key -config server.csr.cnf +openssl x509 -req -in server.csr -CA certs/ca.crt.pem -CAkey private/ca.key.pem -CAcreateserial -out certs/apache.crt -days 3650 -sha256 -extfile v3.ext diff --git a/test/fixtures/files/test_ca/index.txt b/test/fixtures/files/test_ca/index.txt new file mode 100644 index 000000000..e69de29bb diff --git a/test/fixtures/files/test_ca/openssl.cnf b/test/fixtures/files/test_ca/openssl.cnf new file mode 100644 index 000000000..039735751 --- /dev/null +++ b/test/fixtures/files/test_ca/openssl.cnf @@ -0,0 +1,348 @@ +# +# OpenSSL example configuration file. +# This is mostly being used for generation of certificate requests. +# + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . +RANDFILE = $ENV::HOME/.rnd + +# Extra OBJECT IDENTIFIER info: +#oid_file = $ENV::HOME/.oid +oid_section = new_oids + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] + +# We can add new OIDs in here for use by 'ca', 'req' and 'ts'. +# Add a simple OID like this: +# testoid1=1.2.3.4 +# Or use config file substitution like this: +# testoid2=${testoid1}.5.6 + +# Policies used by the TSA examples. +tsa_policy1 = 1.2.3.4.1 +tsa_policy2 = 1.2.3.4.5.6 +tsa_policy3 = 1.2.3.4.5.7 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = /opt/ca # Where everything is kept +certs = $dir/certs # Where the issued certs are kept +crl_dir = $dir/crl # Where the issued crl are kept +database = $dir/index.txt # database index file. +#unique_subject = no # Set to 'no' to allow creation of + # several certs with same subject. +new_certs_dir = $dir/newcerts # default place for new certs. + +certificate = $dir/cacert.pem # The CA certificate +serial = $dir/serial # The current serial number +crlnumber = $dir/crlnumber # the current crl number + # must be commented out to leave a V1 CRL +crl = $dir/crl.pem # The current CRL +private_key = $dir/private/cakey.pem# The private key +RANDFILE = $dir/private/.rand # private random number file + +x509_extensions = usr_cert # The extensions to add to the cert + +# Comment out the following two lines for the "traditional" +# (and highly broken) format. +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +# Extension copying option: use with caution. +# copy_extensions = copy + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crlnumber must also be commented out to leave a V1 CRL. +crl_extensions = crl_ext + +default_days = 365 # how long to certify for +default_crl_days= 30 # how long before next CRL +default_md = default # use public key default MD +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = optional +stateOrProvinceName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +#################################################################### +[ req ] +default_bits = 2048 +default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extensions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString (PKIX recommendation before 2004) +# utf8only: only UTF8Strings (PKIX recommendation after 2004). +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. +string_mask = utf8only + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = EE +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = Harjumaa + +localityName = Locality Name (eg, city) +localityName_default = Tallinn + +0.organizationName = Organization Name (eg, company) +0.organizationName_default = Eesti Interneti Sihtasutus + +# we can do this but it is not needed normally :-) +#1.organizationName = Second Organization Name (eg, company) +#1.organizationName_default = World Wide Web Pty Ltd + +organizationalUnitName = Organizational Unit Name (eg, section) +#organizationalUnitName_default = + +commonName = Common Name (e.g. server FQDN or YOUR name) +commonName_max = 64 + +emailAddress = Email Address +emailAddress_default = hello@internet.ee +emailAddress_max = 64 + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +challengePassword = A challenge password +challengePassword_min = 4 +challengePassword_max = 20 + +unstructuredName = An optional company name + +[ usr_cert ] + +# These extensions are added when 'ca' signs a request. + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +# nsCertType = server + +# For an object signing certificate this would be used. +# nsCertType = objsign + +# For normal client use this is typical +# nsCertType = client, email + +# and for everything including object signing: +# nsCertType = client, email, objsign + +# This is typical in keyUsage for a client certificate. +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "OpenSSL Generated Certificate" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. +# Import the email address. +# subjectAltName=email:copy +# An alternative to produce certificates that aren't +# deprecated according to PKIX. +# subjectAltName=email:move + +# Copy subject details +# issuerAltName=issuer:copy + +#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +# This is required for TSA certificates. +# extendedKeyUsage = critical,timeStamping + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] + + +# Extensions for a typical CA + + +# PKIX recommendation. + +subjectKeyIdentifier=hash + +authorityKeyIdentifier=keyid:always,issuer + +basicConstraints = CA:true + +# Key usage: this is typical for a CA certificate. However since it will +# prevent it being used as an test self-signed certificate it is best +# left out by default. +keyUsage = cRLSign, keyCertSign + +# Some might want this also +# nsCertType = sslCA, emailCA + +# Include email address in subject alt name: another PKIX recommendation +# subjectAltName=email:copy +# Copy issuer details +# issuerAltName=issuer:copy + +# DER hex encoding of an extension: beware experts only! +# obj=DER:02:03 +# Where 'obj' is a standard or added object +# You can even override a supported extension: +# basicConstraints= critical, DER:30:03:01:01:FF + +[ crl_ext ] + +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +# issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + +[ proxy_cert_ext ] +# These extensions should be added when creating a proxy certificate + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +# nsCertType = server + +# For an object signing certificate this would be used. +# nsCertType = objsign + +# For normal client use this is typical +# nsCertType = client, email + +# and for everything including object signing: +# nsCertType = client, email, objsign + +# This is typical in keyUsage for a client certificate. +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "OpenSSL Generated Certificate" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. +# Import the email address. +# subjectAltName=email:copy +# An alternative to produce certificates that aren't +# deprecated according to PKIX. +# subjectAltName=email:move + +# Copy subject details +# issuerAltName=issuer:copy + +#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +# This really needs to be in place for it to be a proxy certificate. +proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo + +#################################################################### +[ tsa ] + +default_tsa = tsa_config1 # the default TSA section + +[ tsa_config1 ] + +# These are used by the TSA reply generation only. +dir = /opt/ca # TSA root directory +serial = $dir/tsaserial # The current serial number (mandatory) +crypto_device = builtin # OpenSSL engine to use for signing +signer_cert = $dir/tsacert.pem # The TSA signing certificate + # (optional) +certs = $dir/cacert.pem # Certificate chain to include in reply + # (optional) +signer_key = $dir/private/tsakey.pem # The TSA private key (optional) +signer_digest = sha256 # Signing digest to use. (Optional) +default_policy = tsa_policy1 # Policy if request did not specify it + # (optional) +other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional) +digests = sha1, sha256, sha384, sha512 # Acceptable message digests (mandatory) +accuracy = secs:1, millisecs:500, microsecs:100 # (optional) +clock_precision_digits = 0 # number of digits after dot. (optional) +ordering = yes # Is ordering defined for timestamps? + # (optional, default: no) +tsa_name = yes # Must the TSA name be included in the reply? + # (optional, default: no) +ess_cert_id_chain = no # Must the ESS cert id chain be included? + # (optional, default: no) diff --git a/test/fixtures/files/test_ca/prepare_root_ca.sh b/test/fixtures/files/test_ca/prepare_root_ca.sh new file mode 100755 index 000000000..41725eb14 --- /dev/null +++ b/test/fixtures/files/test_ca/prepare_root_ca.sh @@ -0,0 +1,8 @@ +# Prepare required files +touch index.txt +echo 1000 > serial +echo 1000 > crlnumber + +# Generate Root CA. +openssl genrsa -aes256 -out private/ca.key.pem 4096 +openssl req -config openssl.cnf -new -x509 -days 365 -key private/ca.key.pem -sha256 -extensions v3_ca -out certs/ca.crt.pem diff --git a/test/fixtures/files/test_ca/private/ca.key.pem b/test/fixtures/files/test_ca/private/ca.key.pem new file mode 100644 index 000000000..c60b8a89e --- /dev/null +++ b/test/fixtures/files/test_ca/private/ca.key.pem @@ -0,0 +1,54 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-256-CBC,AEB2DBECCB8452DE1D6E3F46B4AD32A8 + +i/cuYpPW2lzi/spv5ZOvF5Fw19ZNOqIl42jdxyTKnEa51xKW7nlOUFvglzYiEMS5 +rP4TWqnlBdRl1QXUv9R9zsL6DaPXs0j1kX8OxsV8ZRF6Pzb0G0uJBF7xxKb7c/8j +GP3uURESHhVc4ku6ctkChzTrUd7V4/pPEG5hLFdpgdTNodtfzDGWORFBDv2Jp0Mc +hiJFKnLaCFItRpQnqGKfDwJPRUJIIwjH1EUx+U4WDzUI5z7LhNVZ9A/07hYvSh56 +bwZ4T4CXBXxVtBPhzb5aLigqs6CGfslsQnvoajdKEHq6B1j5Yj0aDG/IYG2jNSJM +9rRbL/0/FPmKrjsbsyxskzp2vRKYOUA2G6SU4Q8db/OBwmaz7zQC+2Og6G115f6/ +TvBNsF+SfiP7YlaRs6qGJLk9NBqqdsTvTli8qGvOV3dAUp1EXB+MGsyQGitG+7+d +7XSenjHN4Lxvb0o0BBHIDv6HScIB8a1ebtLDCV45NdYyM1lsx2rOQyKwVe++TVrH +PI+vHoR+Qx1eC2m+UOzzjtRREXbwMZfe0ErvtTUC+LrU90J48u9lRZglxOR2VdjV +/eHVlTbiWgR8fcbbbBxeVOwilwXC/vRtiYHjMkbAzul4VOPRc0gRJ4VED0mpRSf0 +/n82W9fJnqhWjEV/zoqYUCWaLG/Q/FXE9o81GeI5Av5HNF7SSy3pvxvt+dvU1Cxi +mJGj/w3T5e4yAJi7tPYfRvjyD30WFgIDw3AmJly600B6QAQ2+xi1UPL5kew46haS +Z+bdRb6lPGpDhZXPGRKnTYsoHFbpoE1tYWUMzFzBF1VeCPgPrmjoXzcWVD1tnzu7 +LV01qUfNL/SFnue7oa8xsZj4WMfhB6DsalDf30GdR4HFgswO3rPKWxP2r+tnOscv +MBwlaSvzAY4bx8rLE5Yf46rDvoby/oy3P9ZGrLygraIG4QNOJvSB8esHfXTkT7Mb +IAFPnYWc8CjwsfBTP1wl0qzgbx04FOQfmfqfS67KUcxCN2RSOidhmfrzpZhYSTli +/qpbek3rRSssAZKkuN53ozW5gfwLJpeStuSM/or6C2EKEj7KWYkTEFTRxQtFDfZB +uWdO5836XlsVZdm99OqRUlR4eLqtyGYpZjfaMcjSBbmTs8U7Xxixb6FcLyp6UbeQ +Fa3RJQL3vkINuFzIsxjRi7AUjd18+pFjYC5nOEdoJQBAM83inBrjGyxSKKcdYlVt +j4srLisCMrtDOfijyLzl+cwoUod5DUn8JhgHM1ypIPQ7pk8vYFo38I2YE4I/Djuo +EO6l8SFaWRa6AI/gkBUazwPh2OX/41e/eGeRVbTgfuzlBwJHhW5hyKTD9/DSsSmU +cC96Y9X8pwggPR8s5zLzheOCS9ysEJmgCgPgw02f/Nxydy4VWtEYlIv/C37a3JB5 +Kgtz2icD80vugSF8BkkFpQjwC8fU61pDZ0SdP5WYricakSXya46BUnZk6pS1HmZC +iw6kUrPvQk8l6e0uuB2gWPIisvpoPDuxqccayUWSbZzkV+Q3t7Mjc1uTnVQDCSGo +pdJfOr1asIBSsUzhYbvw5pDBrOTtNT6k3WAdwbhQ31q+jwhzq8ESj7UQ9klsFLlc +nthCeTC6Wv0vNbIdf5YpCR21J1RxRv8XNO1HrN1/uJKcTvrpEVFopKTN5KYnOGlq +rQdA3zetvsncmmOJe+/77pVZ/GT05yCGPlEtdjSb6RJQ3hmOZAeY/KpKh7nrYH7i +Fk+N5EJJHdCbqFLQ//Xi/8Gx5wdpzJGfFx8R0XMkQ2mXwFmqYF/IFDLnMDfp0NWW +A1SVYaQcjTOkOCdVN6CJcs8dfNo3Fm8zoo+8HMO9K1wLMiQopI+UZovIguCXELsC +A+BuzsZsnSb4bFXVq4kXbHW86WfBwoPPjRtYgDXdRyOzEd4QY0wNyBn8Ab3ogJNJ +JqNTic7N9Gg6y2GvGryiEpZL10DFUpsIIx3bdXuBOQTlDRNtj2WyQ+vpMpDwW6iQ +u0zvpvZ60Qf+akU+Z6p/yLCQUZ4JNXsp6qUaEKG3WaIwlQh5bVeWEtAOAqFDS534 +4NZoW/MMpjErHcJcoi3WAVHyq03WlnaCHTRaA5KUgVhAJ+iPh49th7uDjaqlYvC2 +m+eedZuac0wrsPG0UuAZJSqtPpNL5H53WYnuGSUE3OkLxNau+9lEqG7M3lAn7/N3 +NjHiyNvT+3JHxDMK5icSQKvvjzscX57OLneF5jxufbDXCf4fZbnMgFDH0SXOJkxV +ImGAIfaNnmBMz/mpvAGHOGUQxZDRHxvR8fO6BrZBomOmYEiWrhWbp6XRJEz+62M8 +LwE9wQnoobko3xtX+90rHWUp1jIvZRoM3dHSxIEtI2mePPklHC9RpEf9qpiwY+yR +84mI/HGiC5MnBe4BN8BMI1s2pOvLKgaEf5FJRON2nAR1qTDh0BVZx9pby2fheXBr +U80cp5khOjOeNFTJfoTJcxRv43HH4U58Ce1Gra5grB8fhdBjCqUZnX2zsuAOVAcn ++bOMUcHMI9dW6og3Plb09nhTjzLlD3i2+rCBHZOlw9m3nTBALkE8iL0f5/BFxEFy +p3fX1YWoSh/XTKdaKCQsZ9xs1oCZ73h7l1F6+o/qD2PjCkOtI5PRAGmZ83FpKY0G +eRF3vM1guPaV4qpccOqN7qii3MLVEqxWbnM0+ZBfMoHIwSvWgxaallcoyhEgLwkO +9wliM4ORX+csTmdDCJl1URR7pJBRmBMX6a7fqsZPxLQ+VjhYXZDwCohuRSYRaoai +YMVp6s6KutzSt/JUSP1oDYPxIY6pfxq/LMN4R/tBK+bdhQP8EEvcJGjKkzxslThU +utQF9Ml8oBw0LmCsxRnkPfhF2d3PmNX97QPwLBN6q1PvhQLOd1s9ILKSLBN89UCM +P7BrU/m3qcXlkGbbzKjjTMqHlvoCUQnieyAKc3ugWwGc9LIAEaFTLj45B5POXKqk +TYG3ubWWgtwVtWlCO8IMjz3+8jnQ+bHoiBwVA0y3WyQvvwqeU7SnuBHb9ktURUrs +o2LrswBQbDxvfH7T7Iz2e6pvhGMegkNo3LO86e7gaC1shMs4juCT1jy2ln2XexgN +xP8Lo0hkO2UJEVs2OMBjmawbPSEg/p/7cftwMpVUV/Dgl/7viwcLy5RGJff9y5L7 +-----END RSA PRIVATE KEY----- diff --git a/test/fixtures/files/test_ca/serial b/test/fixtures/files/test_ca/serial new file mode 100644 index 000000000..83b33d238 --- /dev/null +++ b/test/fixtures/files/test_ca/serial @@ -0,0 +1 @@ +1000 diff --git a/test/fixtures/files/test_ca/server.csr b/test/fixtures/files/test_ca/server.csr new file mode 100644 index 000000000..1020d46a1 --- /dev/null +++ b/test/fixtures/files/test_ca/server.csr @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIC2DCCAcACAQAwgZIxCzAJBgNVBAYTAkVFMREwDwYDVQQIDAhIYXJqdW1hYTEQ +MA4GA1UEBwwHVGFsbGlubjEZMBcGA1UECgwQRWVzdGlJbnRlcm5ldGlTQTEQMA4G +A1UECwwHQXJlbmR1czEgMB4GCSqGSIb3DQEJARYRaGVsbG9AaW50ZXJuZXQuZWUx +DzANBgNVBAMMBioudGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AKqGSyKRUfemyMMZPRr803k57DzKUyf3yPkll0IeVH5QCBu+B5fmgVvpPIyGflcc +F8J+7sGO33bXprvQswqmCuKamYNevCBAtNFZ3gu4In2jFoAXfwzYr9xWnzaU4oXT +Ga2YvMSySLjcPFy2g3mxkK63zlsNQnsLpvzCWiBZyAbbbAavoxcCrQCfUYDYOlJd +sThqaray5lNtR5iM5vYam3mliDSF9UA1QtmVnYFV4KBCA/0S1HPAPq4lVHWisxvZ +Aq7bsxjvD4V6BeQSVrbKwHGBUHr941USqZUhYcIYo4djGNeKgNtcLHjTBe/n0go4 +brxKJsaczUEh9FAAx1tKde8CAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQAkJkKR +jqptkp2vkHUH/Nnmqh9SCPD5wETGtGLZzS/ZnWAyRPHZ8Kw3XnCvyZj41EnWifWC ++0kKSpQTvhED8RPmgfE1piQtSPuFJ9f26vyag5sGPfUkBaBl6zaxpK3fDHpCercy +N5J6b1FAoWj/rhtRCMJx8OYCmurBp4BUtyYbduk0FWhdcX8uyRiLOOxaGO7ZpkEf +CEUhEarperXPqhm9NtNbPrEP15tunf5otM6FjpIoc0wFtlOUdrZBT9dE+67F8WlT +qlXUSXucrhWt/WXEiuzaj6w/J7prDr9ua/xO9qUo5aWA6QlPsSsaQl9KF9ST0qXG +hm/lggFVtkCvKv5L +-----END CERTIFICATE REQUEST----- diff --git a/test/fixtures/files/test_ca/server.csr.cnf b/test/fixtures/files/test_ca/server.csr.cnf new file mode 100644 index 000000000..b4b38b465 --- /dev/null +++ b/test/fixtures/files/test_ca/server.csr.cnf @@ -0,0 +1,14 @@ +[req] +default_bits = 2048 +prompt = no +default_md = sha256 +distinguished_name = dn + +[dn] +C=EE +ST=Harjumaa +L=Tallinn +O=EestiInternetiSA +OU=Arendus +emailAddress=hello@internet.ee +CN = *.test diff --git a/test/fixtures/files/test_ca/v3.ext b/test/fixtures/files/test_ca/v3.ext new file mode 100644 index 000000000..82646bc5b --- /dev/null +++ b/test/fixtures/files/test_ca/v3.ext @@ -0,0 +1,8 @@ +authorityKeyIdentifier=keyid,issuer +basicConstraints=CA:FALSE +keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment +subjectAltName = @alt_names + +[alt_names] +DNS.1 = test +DNS.2 = registry.test diff --git a/test/fixtures/invoice_items.yml b/test/fixtures/invoice_items.yml index 19409df81..a61ef4eb0 100644 --- a/test/fixtures/invoice_items.yml +++ b/test/fixtures/invoice_items.yml @@ -4,3 +4,10 @@ one: quantity: 1 unit: pc invoice: one + +two: + description: Acme services + price: 5 + quantity: 1 + unit: pc + invoice: unpaid diff --git a/test/fixtures/invoices.yml b/test/fixtures/invoices.yml index c3e3bac79..6c0dca021 100644 --- a/test/fixtures/invoices.yml +++ b/test/fixtures/invoices.yml @@ -3,10 +3,51 @@ one: due_date: <%= Date.parse '2010-07-06' %> currency: EUR seller_name: Seller Ltd + seller_reg_no: 1234 seller_iban: US75512108001245126199 + seller_bank: Main Bank + seller_swift: swift + seller_email: info@seller.test + seller_country_code: US + seller_street: Main Street 1 + seller_city: New York + seller_contact_name: John Doe buyer: bestnames buyer_name: Buyer Ltd + buyer_reg_no: 12345 + buyer_email: info@buyer.test + buyer_country_code: GB + buyer_street: Main Street 2 + buyer_city: London vat_rate: 0.1 total: 16.50 reference_no: 13 - number: 1 \ No newline at end of file + number: 1 + description: Order nr 1 from registrar 1234567 second number 2345678 + +unpaid: + issue_date: <%= Date.parse '2010-07-05' %> + due_date: <%= Date.parse '2010-07-06' %> + currency: EUR + seller_name: Seller Ltd + seller_reg_no: 1234 + seller_iban: US75512108001245126199 + seller_bank: Main Bank + seller_swift: swift + seller_email: info@seller.test + seller_country_code: US + seller_street: Main Street 1 + seller_city: New York + seller_contact_name: John Doe + buyer: bestnames + buyer_name: Buyer Ltd + buyer_reg_no: 12345 + buyer_email: info@buyer.test + buyer_country_code: GB + buyer_street: Main Street 2 + buyer_city: London + vat_rate: 0.1 + total: 16.50 + reference_no: 13 + number: 2 + description: Order nr 2 from registrar 1234567 second number 2345678 diff --git a/test/fixtures/payment_orders.yml b/test/fixtures/payment_orders.yml new file mode 100644 index 000000000..39289b7d1 --- /dev/null +++ b/test/fixtures/payment_orders.yml @@ -0,0 +1,27 @@ +everypay_issued: + type: PaymentOrders::EveryPay + status: issued + invoice: one + response: + notes: + +banklink_issued: + type: PaymentOrders::Seb + status: issued + invoice: one + response: + notes: + +paid: + type: PaymentOrders::EveryPay + status: paid + invoice: unpaid + response: "{}" + notes: + +cancelled: + type: PaymentOrders::Seb + status: cancelled + invoice: unpaid + response: "{}" + notes: User failed to make payment. Bank responded with code 1911 diff --git a/test/fixtures/registrant_verifications.yml b/test/fixtures/registrant_verifications.yml new file mode 100644 index 000000000..bc3be67db --- /dev/null +++ b/test/fixtures/registrant_verifications.yml @@ -0,0 +1,6 @@ +one: + action: confirmed + action_type: domain_delete + created_at: <%= Time.zone.parse('2010-07-05') %> + domain: shop + verification_token: 1234 diff --git a/test/fixtures/setting_entries.yml b/test/fixtures/setting_entries.yml new file mode 100644 index 000000000..067f77c12 --- /dev/null +++ b/test/fixtures/setting_entries.yml @@ -0,0 +1,464 @@ +registry_vat_prc: + code: registry_vat_prc + value: '0.2' + group: billing + format: float + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +directo_sales_agent: + code: directo_sales_agent + value: HELEN + group: billing + format: string + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +admin_contacts_min_count: + code: admin_contacts_min_count + value: '1' + group: domain_validation + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +admin_contacts_max_count: + code: admin_contacts_max_count + value: '10' + group: domain_validation + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +tech_contacts_min_count: + code: tech_contacts_min_count + value: '1' + group: domain_validation + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +tech_contacts_max_count: + code: tech_contacts_max_count + value: '10' + group: domain_validation + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +orphans_contacts_in_months: + code: orphans_contacts_in_months + value: '6' + group: domain_validation + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +ds_data_allowed: + code: ds_data_allowed + value: 'false' + group: domain_validation + format: boolean + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +key_data_allowed: + code: key_data_allowed + value: 'true' + group: domain_validation + format: boolean + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +dnskeys_min_count: + code: dnskeys_min_count + value: '0' + group: domain_validation + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +dnskeys_max_count: + code: dnskeys_max_count + value: '9' + group: domain_validation + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +nameserver_required: + code: nameserver_required + value: 'false' + group: domain_validation + format: boolean + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +ns_min_count: + code: ns_min_count + value: '2' + group: domain_validation + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +ns_max_count: + code: ns_max_count + value: '11' + group: domain_validation + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +expire_pending_confirmation: + code: expire_pending_confirmation + value: '48' + group: domain_validation + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +days_to_renew_domain_before_expire: + code: days_to_renew_domain_before_expire + value: '90' + group: domain_expiration + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +expire_warning_period: + code: expire_warning_period + value: '15' + group: domain_expiration + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +redemption_grace_period: + code: redemption_grace_period + value: '30' + group: domain_expiration + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +transfer_wait_time: + code: transfer_wait_time + value: '0' + group: other + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +ds_digest_type: + code: ds_digest_type + value: '2' + group: other + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +client_side_status_editing_enabled: + code: client_side_status_editing_enabled + value: 'false' + group: other + format: boolean + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +api_ip_whitelist_enabled: + code: api_ip_whitelist_enabled + value: 'false' + group: other + format: boolean + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +registrar_ip_whitelist_enabled: + code: registrar_ip_whitelist_enabled + value: 'false' + group: other + format: boolean + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +request_confrimation_on_registrant_change_enabled: + code: request_confrimation_on_registrant_change_enabled + value: 'true' + group: other + format: boolean + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +request_confirmation_on_domain_deletion_enabled: + code: request_confirmation_on_domain_deletion_enabled + value: 'true' + group: other + format: boolean + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +default_language: + code: default_language + value: en + group: other + format: string + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +invoice_number_min: + code: invoice_number_min + value: '131050' + group: billing + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +invoice_number_max: + code: invoice_number_max + value: '149999' + group: billing + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +days_to_keep_invoices_active: + code: days_to_keep_invoices_active + value: '30' + group: billing + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +days_to_keep_overdue_invoices_active: + code: days_to_keep_overdue_invoices_active + value: '0' + group: billing + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +minimum_deposit: + code: minimum_deposit + value: '0.0' + group: billing + format: float + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +directo_receipt_payment_term: + code: directo_receipt_payment_term + value: R + group: billing + format: string + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +directo_receipt_product_name: + code: directo_receipt_product_name + value: ETTEM06 + group: billing + format: string + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +registry_billing_email: + code: registry_billing_email + value: info@internet.ee + group: billing + format: string + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +registry_invoice_contact: + code: registry_invoice_contact + value: 'Martti Õigus' + group: billing + format: string + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +registry_vat_no: + code: registry_vat_no + value: EE101286464 + group: billing + format: string + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +registry_bank: + code: registry_bank + value: 'LHV Pank' + group: billing + format: string + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +registry_iban: + code: registry_iban + value: EE557700771000598731 + group: billing + format: string + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +registry_swift: + code: registry_swift + value: LHVBEE22 + group: billing + format: string + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +registry_email: + code: registry_email + value: info@internet.ee + group: contacts + format: string + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +registry_phone: + code: registry_phone + value: '+372 727 1000' + group: contacts + format: string + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +registry_url: + code: registry_url + value: www.internet.ee + group: contacts + format: string + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +registry_street: + code: registry_street + value: 'Paldiski mnt 80' + group: contacts + format: string + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +registry_city: + code: registry_city + value: Tallinn + group: contacts + format: string + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +registry_state: + code: registry_state + value: Harjumaa + group: contacts + format: string + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +registry_country_code: + code: registry_country_code + value: US + group: contacts + format: string + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +expiration_reminder_mail: + code: expiration_reminder_mail + value: '2' + group: domain_expiration + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +directo_monthly_number_min: + code: directo_monthly_number_min + value: '309901' + group: billing + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +directo_monthly_number_max: + code: directo_monthly_number_max + value: '309999' + group: billing + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +registry_bank_code: + code: registry_bank_code + value: '689' + group: billing + format: string + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +registry_reg_no: + code: registry_reg_no + value: '90010019' + group: contacts + format: string + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +registry_zip: + code: registry_zip + value: '10617' + group: contacts + format: string + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +registry_juridical_name: + code: registry_juridical_name + value: 'Eesti Interneti SA' + group: contacts + format: string + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +address_processing: + code: address_processing + value: 'false' + group: other + format: boolean + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +directo_monthly_number_last: + code: directo_monthly_number_last + value: '309901' + group: billing + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +dispute_period_in_months: + code: dispute_period_in_months + value: '36' + group: other + format: integer + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +registry_whois_disclaimer: + code: registry_whois_disclaimer + value: 'Search results may not be used for commercial, advertising, recompilation, + repackaging, redistribution, reuse, obscuring or other similar activities.' + group: contacts + format: string + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> + +legal_document_is_mandatory: + code: legal_document_is_mandatory + value: 'true' + group: domain_validation + format: boolean + created_at: <%= Time.zone.parse('2010-07-05') %> + updated_at: <%= Time.zone.parse('2010-07-05') %> diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml index 49508c0cf..c507a6b8a 100644 --- a/test/fixtures/users.yml +++ b/test/fixtures/users.yml @@ -19,6 +19,7 @@ api_goodnames: admin: username: test + email: test@registry.test encrypted_password: <%= Devise::Encryptor.digest(AdminUser, 'testtest') %> type: AdminUser country_code: US diff --git a/test/integration/admin_area/disputes_test.rb b/test/integration/admin_area/disputes_test.rb new file mode 100644 index 000000000..81019bb66 --- /dev/null +++ b/test/integration/admin_area/disputes_test.rb @@ -0,0 +1,91 @@ +require 'application_system_test_case' +require 'test_helper' + +class AdminDisputesSystemTest < ApplicationSystemTestCase + include ActionView::Helpers::NumberHelper + + setup do + @dispute = disputes(:active) + @original_default_language = Setting.default_language + sign_in users(:admin) + end + + teardown do + Setting.default_language = @original_default_language + end + + def test_creates_new_dispute + assert_nil Dispute.active.find_by(domain_name: 'hospital.test') + + visit admin_disputes_path + click_on 'New disputed domain' + + fill_in 'Domain name', with: 'hospital.test' + fill_in 'Password', with: '1234' + fill_in 'Starts at', with: (Time.zone.today - 2.years).to_s + fill_in 'Comment', with: 'Sample comment' + click_on 'Save' + + assert_text 'Dispute was successfully created.' + assert_text 'hospital.test' + end + + def test_creates_new_dispute_for_unregistered_domain + assert_nil Dispute.active.find_by(domain_name: 'nonexistant.test') + + visit admin_disputes_path + click_on 'New disputed domain' + + fill_in 'Domain name', with: 'nonexistant.test' + fill_in 'Password', with: '1234' + fill_in 'Starts at', with: Time.zone.today.to_s + fill_in 'Comment', with: 'Sample comment' + click_on 'Save' + + assert_text 'Dispute was successfully created for domain that is not registered.' + assert_text 'nonexistant.test' + end + + def test_throws_error_if_starts_at_is_in_future + assert_nil Dispute.active.find_by(domain_name: 'disputed.test') + + visit admin_disputes_path + click_on 'New disputed domain' + + fill_in 'Domain name', with: 'disputed.test' + fill_in 'Password', with: '1234' + fill_in 'Starts at', with: (Time.zone.today + 2.day).to_s + fill_in 'Comment', with: 'Sample comment' + click_on 'Save' + + assert_text "Can not be greater than today's date" + end + + def test_updates_dispute + assert_not_equal Time.zone.today, @dispute.starts_at + + visit edit_admin_dispute_path(@dispute) + fill_in 'Starts at', with: Time.zone.today.to_s + click_link_or_button 'Save' + + assert_text 'Dispute was successfully updated' + assert_text Time.zone.today + end + + def test_deletes_dispute + visit delete_admin_dispute_path(@dispute) + + assert_text 'Dispute was successfully closed.' + end + + def test_can_not_create_overlapping_dispute + visit admin_disputes_path + click_on 'New disputed domain' + + fill_in 'Domain name', with: 'active-dispute.test' + fill_in 'Starts at', with: @dispute.starts_at + 1.day + click_on 'Save' + + assert_text 'Dispute already exists for this domain at given timeframe' + end +end diff --git a/test/integration/admin_area/invoices_test.rb b/test/integration/admin_area/invoices_test.rb index 204f953d8..887f57212 100644 --- a/test/integration/admin_area/invoices_test.rb +++ b/test/integration/admin_area/invoices_test.rb @@ -13,7 +13,7 @@ class AdminAreaInvoicesIntegrationTest < ApplicationIntegrationTest assert_response :ok assert_equal 'application/pdf', response.headers['Content-Type'] - assert_equal 'attachment; filename="invoice-1.pdf"', response.headers['Content-Disposition'] + assert_equal "attachment; filename=\"invoice-1.pdf\"; filename*=UTF-8''invoice-1.pdf", response.headers['Content-Disposition'] assert_not_empty response.body end -end \ No newline at end of file +end diff --git a/test/integration/admin_area/registrars_test.rb b/test/integration/admin_area/registrars_test.rb index 009e7c6d6..d73496899 100644 --- a/test/integration/admin_area/registrars_test.rb +++ b/test/integration/admin_area/registrars_test.rb @@ -12,7 +12,7 @@ class AdminAreaRegistrarsIntegrationTest < ActionDispatch::IntegrationTest new_iban = 'GB94BARC10201530093459' assert_not_equal new_iban, @registrar.iban - patch admin_registrar_path(@registrar), registrar: { iban: new_iban } + patch admin_registrar_path(@registrar), params: { registrar: { iban: new_iban } } @registrar.reload assert_equal new_iban, @registrar.iban diff --git a/test/integration/admin_area/zones_test.rb b/test/integration/admin_area/zones_test.rb new file mode 100644 index 000000000..bf7c07d7b --- /dev/null +++ b/test/integration/admin_area/zones_test.rb @@ -0,0 +1,27 @@ +require 'test_helper' + +class AdminAreaZonesIntegrationTest < ApplicationIntegrationTest + setup do + @zone = dns_zones(:one) + sign_in users(:admin) + end + + def test_updates_zone + new_master_nameserver = 'new.test' + assert_not_equal new_master_nameserver, @zone.master_nameserver + + patch admin_zone_path(@zone), params: { zone: { master_nameserver: new_master_nameserver } } + @zone.reload + + assert_equal new_master_nameserver, @zone.master_nameserver + end + + def test_downloads_zone_file + post admin_zonefiles_path(origin: @zone.origin) + + assert_response :ok + assert_equal 'text/plain', response.headers['Content-Type'] + assert_equal "attachment; filename=\"test.txt\"; filename*=UTF-8''test.txt", response.headers['Content-Disposition'] + assert_not_empty response.body + end +end diff --git a/test/integration/api/domain_contacts_test.rb b/test/integration/api/domain_contacts_test.rb index e99a45825..5336cc10a 100644 --- a/test/integration/api/domain_contacts_test.rb +++ b/test/integration/api/domain_contacts_test.rb @@ -2,9 +2,9 @@ require 'test_helper' class APIDomainContactsTest < ApplicationIntegrationTest def test_replace_all_tech_contacts_of_the_current_registrar - patch '/repp/v1/domains/contacts', { current_contact_id: 'william-001', - new_contact_id: 'john-001' }, - { 'HTTP_AUTHORIZATION' => http_auth_key } + patch '/repp/v1/domains/contacts', params: { current_contact_id: 'william-001', + new_contact_id: 'john-001' }, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } assert_nil domains(:shop).tech_contacts.find_by(code: 'william-001') assert domains(:shop).tech_contacts.find_by(code: 'john-001') @@ -14,17 +14,17 @@ class APIDomainContactsTest < ApplicationIntegrationTest def test_skip_discarded_domains domains(:airport).update!(statuses: [DomainStatus::DELETE_CANDIDATE]) - patch '/repp/v1/domains/contacts', { current_contact_id: 'william-001', - new_contact_id: 'john-001' }, - { 'HTTP_AUTHORIZATION' => http_auth_key } + patch '/repp/v1/domains/contacts', params: { current_contact_id: 'william-001', + new_contact_id: 'john-001' }, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } assert domains(:airport).tech_contacts.find_by(code: 'william-001') end def test_return_affected_domains_in_alphabetical_order - patch '/repp/v1/domains/contacts', { current_contact_id: 'william-001', - new_contact_id: 'john-001' }, - { 'HTTP_AUTHORIZATION' => http_auth_key } + patch '/repp/v1/domains/contacts', params: { current_contact_id: 'william-001', + new_contact_id: 'john-001' }, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } assert_response :ok assert_equal ({ affected_domains: %w[airport.test shop.test], @@ -36,9 +36,9 @@ class APIDomainContactsTest < ApplicationIntegrationTest domains(:shop).update!(statuses: [DomainStatus::DELETE_CANDIDATE]) domains(:airport).update!(statuses: [DomainStatus::DELETE_CANDIDATE]) - patch '/repp/v1/domains/contacts', { current_contact_id: 'william-001', - new_contact_id: 'john-001' }, - { 'HTTP_AUTHORIZATION' => http_auth_key } + patch '/repp/v1/domains/contacts', params: { current_contact_id: 'william-001', + new_contact_id: 'john-001' }, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } assert_response :ok assert_equal %w[airport.test shop.test], JSON.parse(response.body, @@ -46,25 +46,25 @@ class APIDomainContactsTest < ApplicationIntegrationTest end def test_keep_other_tech_contacts_intact - patch '/repp/v1/domains/contacts', { current_contact_id: 'william-001', - new_contact_id: 'john-001' }, - { 'HTTP_AUTHORIZATION' => http_auth_key } + patch '/repp/v1/domains/contacts', params: { current_contact_id: 'william-001', + new_contact_id: 'john-001' }, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } assert domains(:shop).tech_contacts.find_by(code: 'acme-ltd-001') end def test_keep_admin_contacts_intact - patch '/repp/v1/domains/contacts', { current_contact_id: 'william-001', - new_contact_id: 'john-001' }, - { 'HTTP_AUTHORIZATION' => http_auth_key } + patch '/repp/v1/domains/contacts', params: { current_contact_id: 'william-001', + new_contact_id: 'john-001' }, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } assert domains(:airport).admin_contacts.find_by(code: 'william-001') end def test_restrict_contacts_to_the_current_registrar - patch '/repp/v1/domains/contacts', { current_contact_id: 'jack-001', - new_contact_id: 'william-002' }, - { 'HTTP_AUTHORIZATION' => http_auth_key } + patch '/repp/v1/domains/contacts', params: { current_contact_id: 'jack-001', + new_contact_id: 'william-002' }, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } assert_response :bad_request assert_equal ({ error: { type: 'invalid_request_error', @@ -74,9 +74,9 @@ class APIDomainContactsTest < ApplicationIntegrationTest end def test_non_existent_current_contact - patch '/repp/v1/domains/contacts', { current_contact_id: 'non-existent', - new_contact_id: 'john-001' }, - { 'HTTP_AUTHORIZATION' => http_auth_key } + patch '/repp/v1/domains/contacts', params: { current_contact_id: 'non-existent', + new_contact_id: 'john-001' }, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } assert_response :bad_request assert_equal ({ error: { type: 'invalid_request_error', param: 'current_contact_id', @@ -85,9 +85,9 @@ class APIDomainContactsTest < ApplicationIntegrationTest end def test_non_existent_new_contact - patch '/repp/v1/domains/contacts', { current_contact_id: 'william-001', - new_contact_id: 'non-existent' }, - { 'HTTP_AUTHORIZATION' => http_auth_key } + patch '/repp/v1/domains/contacts', params: { current_contact_id: 'william-001', + new_contact_id: 'non-existent' }, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } assert_response :bad_request assert_equal ({ error: { type: 'invalid_request_error', param: 'new_contact_id', @@ -96,9 +96,9 @@ class APIDomainContactsTest < ApplicationIntegrationTest end def test_disallow_invalid_new_contact - patch '/repp/v1/domains/contacts', { current_contact_id: 'william-001', - new_contact_id: 'invalid' }, - { 'HTTP_AUTHORIZATION' => http_auth_key } + patch '/repp/v1/domains/contacts', params: { current_contact_id: 'william-001', + new_contact_id: 'invalid' }, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } assert_response :bad_request assert_equal ({ error: { type: 'invalid_request_error', param: 'new_contact_id', @@ -107,9 +107,9 @@ class APIDomainContactsTest < ApplicationIntegrationTest end def test_disallow_self_replacement - patch '/repp/v1/domains/contacts', { current_contact_id: 'william-001', - new_contact_id: 'william-001' }, - { 'HTTP_AUTHORIZATION' => http_auth_key } + patch '/repp/v1/domains/contacts', params: { current_contact_id: 'william-001', + new_contact_id: 'william-001' }, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } assert_response :bad_request assert_equal ({ error: { type: 'invalid_request_error', message: 'New contact ID must be different from current contact ID' } }), diff --git a/test/integration/api/domain_transfers_test.rb b/test/integration/api/domain_transfers_test.rb index 12c8351f6..aabaeb728 100644 --- a/test/integration/api/domain_transfers_test.rb +++ b/test/integration/api/domain_transfers_test.rb @@ -4,11 +4,17 @@ class APIDomainTransfersTest < ApplicationIntegrationTest setup do @domain = domains(:shop) @new_registrar = registrars(:goodnames) + @original_transfer_wait_time = Setting.transfer_wait_time Setting.transfer_wait_time = 0 # Auto-approval end + teardown do + Setting.transfer_wait_time = @original_transfer_wait_time + end + def test_returns_domain_transfers - post '/repp/v1/domain_transfers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key } + post '/repp/v1/domain_transfers', params: request_params, as: :json, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } assert_response 200 assert_equal ({ data: [{ type: 'domain_transfer', @@ -21,17 +27,20 @@ class APIDomainTransfersTest < ApplicationIntegrationTest def test_creates_new_domain_transfer assert_difference -> { @domain.transfers.size } do - post '/repp/v1/domain_transfers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key } + post '/repp/v1/domain_transfers', params: request_params, as: :json, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } end end def test_approves_automatically_if_auto_approval_is_enabled - post '/repp/v1/domain_transfers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key } + post '/repp/v1/domain_transfers', params: request_params, as: :json, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } assert @domain.transfers.last.approved? end def test_assigns_new_registrar - post '/repp/v1/domain_transfers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key } + post '/repp/v1/domain_transfers', params: request_params, as: :json, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } @domain.reload assert_equal @new_registrar, @domain.registrar end @@ -39,7 +48,8 @@ class APIDomainTransfersTest < ApplicationIntegrationTest def test_regenerates_transfer_code @old_transfer_code = @domain.transfer_code - post '/repp/v1/domain_transfers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key } + post '/repp/v1/domain_transfers', params: request_params, as: :json, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } @domain.reload refute_equal @domain.transfer_code, @old_transfer_code end @@ -48,34 +58,41 @@ class APIDomainTransfersTest < ApplicationIntegrationTest @old_registrar = @domain.registrar assert_difference -> { @old_registrar.notifications.count } do - post '/repp/v1/domain_transfers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key } + post '/repp/v1/domain_transfers', params: request_params, as: :json, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } end end def test_duplicates_registrant_admin_and_tech_contacts assert_difference -> { @new_registrar.contacts.size }, 3 do - post '/repp/v1/domain_transfers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key } + post '/repp/v1/domain_transfers', params: request_params, as: :json, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } end end def test_reuses_identical_contact - post '/repp/v1/domain_transfers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key } + post '/repp/v1/domain_transfers', params: request_params, as: :json, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } assert_equal 1, @new_registrar.contacts.where(name: 'William').size end def test_fails_if_domain_does_not_exist - request_params = { format: :json, - data: { domainTransfers: [{ domainName: 'non-existent.test', transferCode: 'any' }] } } - post '/repp/v1/domain_transfers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key } + post '/repp/v1/domain_transfers', + params: { data: { domainTransfers: [{ domainName: 'non-existent.test', + transferCode: 'any' }] } }, + as: :json, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } assert_response 400 assert_equal ({ errors: [{ title: 'non-existent.test does not exist' }] }), JSON.parse(response.body, symbolize_names: true) end def test_fails_if_transfer_code_is_wrong - request_params = { format: :json, - data: { domainTransfers: [{ domainName: 'shop.test', transferCode: 'wrong' }] } } - post '/repp/v1/domain_transfers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key } + post '/repp/v1/domain_transfers', + params: { data: { domainTransfers: [{ domainName: 'shop.test', + transferCode: 'wrong' }] } }, + as: :json, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } assert_response 400 refute_equal @new_registrar, @domain.registrar assert_equal ({ errors: [{ title: 'shop.test transfer code is wrong' }] }), @@ -85,8 +102,7 @@ class APIDomainTransfersTest < ApplicationIntegrationTest private def request_params - { format: :json, - data: { domainTransfers: [{ domainName: 'shop.test', transferCode: '65078d5' }] } } + { data: { domainTransfers: [{ domainName: 'shop.test', transferCode: '65078d5' }] } } end def http_auth_key diff --git a/test/integration/api/nameservers/put_test.rb b/test/integration/api/nameservers/put_test.rb index 4c35d3e77..853a20549 100644 --- a/test/integration/api/nameservers/put_test.rb +++ b/test/integration/api/nameservers/put_test.rb @@ -5,18 +5,23 @@ class APINameserversPutTest < ApplicationIntegrationTest old_nameserver_ids = [nameservers(:shop_ns1).id, nameservers(:airport_ns1).id, nameservers(:metro_ns1).id] - request_params = { format: :json, data: { type: 'nameserver', id: 'ns1.bestnames.test', - attributes: { hostname: 'ns55.bestnames.test' } } } - put '/repp/v1/registrar/nameservers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key } - assert_empty (old_nameserver_ids & registrars(:bestnames).nameservers(true).ids) + params = { data: { type: 'nameserver', + id: 'ns1.bestnames.test', + attributes: { hostname: 'ns55.bestnames.test' } } } + + put '/repp/v1/registrar/nameservers', params: params, as: :json, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } + + assert_empty (old_nameserver_ids & registrars(:bestnames).nameservers.reload.ids) end def test_saves_all_attributes - request_params = { format: :json, data: { type: 'nameserver', id: 'ns1.bestnames.test', - attributes: { hostname: 'ns55.bestnames.test', - ipv4: ['192.0.2.55'], - ipv6: ['2001:db8::55'] } } } - put '/repp/v1/registrar/nameservers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key } + params = { data: { type: 'nameserver', id: 'ns1.bestnames.test', + attributes: { hostname: 'ns55.bestnames.test', + ipv4: ['192.0.2.55'], + ipv6: ['2001:db8::55'] } } } + put '/repp/v1/registrar/nameservers', params: params, as: :json, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } new_nameserver = domains(:shop).nameservers.find_by(hostname: 'ns55.bestnames.test') assert_equal ['192.0.2.55'], new_nameserver.ipv4 @@ -24,52 +29,60 @@ class APINameserversPutTest < ApplicationIntegrationTest end def test_keeps_other_nameserver_intact - request_params = { format: :json, data: { type: 'nameserver', id: 'ns1.bestnames.test', - attributes: { hostname: 'ns55.bestnames.test' } } } + params = { data: { type: 'nameserver', id: 'ns1.bestnames.test', + attributes: { hostname: 'ns55.bestnames.test' } } } other_nameserver_hash = nameservers(:shop_ns2).attributes - put '/repp/v1/registrar/nameservers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key } + put '/repp/v1/registrar/nameservers', params: params, as: :json, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } + assert_equal other_nameserver_hash, nameservers(:shop_ns2).reload.attributes end def test_keeps_other_registrar_nameservers_intact - request_params = { format: :json, data: { type: 'nameserver', id: 'ns1.bestnames.test', - attributes: { hostname: 'ns55.bestnames.test' } } } + params = { data: { type: 'nameserver', id: 'ns1.bestnames.test', + attributes: { hostname: 'ns55.bestnames.test' } } } nameserver_hash = nameservers(:metro_ns1).attributes - put '/repp/v1/registrar/nameservers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key } + put '/repp/v1/registrar/nameservers', params: params, as: :json, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } + assert_equal nameserver_hash, nameservers(:metro_ns1).reload.attributes end def test_returns_new_nameserver_record_and_affected_domain - request_params = { format: :json, data: { type: 'nameserver', id: 'ns1.bestnames.test', - attributes: { hostname: 'ns55.bestnames.test', - ipv4: ['192.0.2.55'], - ipv6: ['2001:db8::55'] } } } + params = { data: { type: 'nameserver', id: 'ns1.bestnames.test', + attributes: { hostname: 'ns55.bestnames.test', + ipv4: ['192.0.2.55'], + ipv6: ['2001:db8::55'] } } } - put '/repp/v1/registrar/nameservers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key } + put '/repp/v1/registrar/nameservers', params: params, as: :json, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } assert_response 200 assert_equal ({ data: { type: 'nameserver', id: 'ns55.bestnames.test', attributes: { hostname: 'ns55.bestnames.test', ipv4: ['192.0.2.55'], - ipv6: ['2001:db8::55'] }}, + ipv6: ['2001:db8::55'] } }, affected_domains: ["airport.test", "shop.test"] }), JSON.parse(response.body, symbolize_names: true) end def test_optional_params - request_params = { format: :json, data: { type: 'nameserver', id: 'ns1.bestnames.test', - attributes: { hostname: 'ns55.bestnames.test' } } } - put '/repp/v1/registrar/nameservers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key } + params = { data: { type: 'nameserver', id: 'ns1.bestnames.test', + attributes: { hostname: 'ns55.bestnames.test' } } } + put '/repp/v1/registrar/nameservers', params: params, as: :json, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } + assert_response 200 end def test_non_existent_nameserver_hostname - request_params = { format: :json, data: { type: 'nameserver', id: 'non-existent.test', - attributes: { hostname: 'any.bestnames.test' } } } - put '/repp/v1/registrar/nameservers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key } + params = { data: { type: 'nameserver', id: 'non-existent.test', + attributes: { hostname: 'any.bestnames.test' } } } + put '/repp/v1/registrar/nameservers', params: params, as: :json, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } assert_response 404 assert_equal ({ errors: [{ title: 'Hostname non-existent.test does not exist' }] }), @@ -77,9 +90,10 @@ class APINameserversPutTest < ApplicationIntegrationTest end def test_invalid_request_params - request_params = { format: :json, data: { type: 'nameserver', id: 'ns1.bestnames.test', - attributes: { hostname: '' } } } - put '/repp/v1/registrar/nameservers', request_params, { 'HTTP_AUTHORIZATION' => http_auth_key } + params = { data: { type: 'nameserver', id: 'ns1.bestnames.test', + attributes: { hostname: '' } } } + put '/repp/v1/registrar/nameservers', params: params, as: :json, + headers: { 'HTTP_AUTHORIZATION' => http_auth_key } assert_response 400 assert_equal ({ errors: [{ title: 'Hostname is missing' }] }), diff --git a/test/integration/api/registrant/registrant_api_authentication_test.rb b/test/integration/api/registrant/registrant_api_authentication_test.rb index 10858d005..9daeabfca 100644 --- a/test/integration/api/registrant/registrant_api_authentication_test.rb +++ b/test/integration/api/registrant/registrant_api_authentication_test.rb @@ -20,7 +20,7 @@ class RegistrantApiAuthenticationTest < ApplicationIntegrationTest last_name: 'Smith', } - post '/api/v1/registrant/auth/eid', params + post '/api/v1/registrant/auth/eid', params: params assert(User.find_by(registrant_ident: 'EE-30110100103')) json = JSON.parse(response.body, symbolize_names: true) @@ -29,7 +29,7 @@ class RegistrantApiAuthenticationTest < ApplicationIntegrationTest def test_request_returns_existing_user assert_no_changes User.count do - post '/api/v1/registrant/auth/eid', @user_hash + post '/api/v1/registrant/auth/eid', params: @user_hash end end @@ -38,7 +38,7 @@ class RegistrantApiAuthenticationTest < ApplicationIntegrationTest @original_whitelist_ip = ENV['registrant_api_auth_allowed_ips'] ENV['registrant_api_auth_allowed_ips'] = '1.2.3.4' - post '/api/v1/registrant/auth/eid', params + post '/api/v1/registrant/auth/eid', params: params assert_equal(401, response.status) json_body = JSON.parse(response.body, symbolize_names: true) @@ -50,7 +50,7 @@ class RegistrantApiAuthenticationTest < ApplicationIntegrationTest def test_request_documented_parameters_are_required params = { foo: :bar, test: :test } - post '/api/v1/registrant/auth/eid', params + post '/api/v1/registrant/auth/eid', params: params json = JSON.parse(response.body, symbolize_names: true) assert_equal({ errors: [{ ident: ['parameter is required'] }] }, json) assert_equal(422, response.status) diff --git a/test/integration/api/registrant/registrant_api_contacts_test.rb b/test/integration/api/registrant/registrant_api_contacts_test.rb index 0658ecac1..af57c1c1a 100644 --- a/test/integration/api/registrant/registrant_api_contacts_test.rb +++ b/test/integration/api/registrant/registrant_api_contacts_test.rb @@ -12,20 +12,21 @@ class RegistrantApiContactsTest < ApplicationIntegrationTest def test_root_accepts_limit_and_offset_parameters contacts(:william).update!(ident: '1234', ident_type: 'priv', ident_country_code: 'US') - assert_equal 3, @user.contacts.size + assert_equal 4, @user.contacts.size - get '/api/v1/registrant/contacts', { 'limit' => 1, 'offset' => 0 }, @auth_headers + get '/api/v1/registrant/contacts', params: { 'limit' => 1, 'offset' => 0 }, + headers: @auth_headers response_json = JSON.parse(response.body, symbolize_names: true) assert_equal(200, response.status) assert_equal(1, response_json.count) - get '/api/v1/registrant/contacts', {}, @auth_headers + get '/api/v1/registrant/contacts', headers: @auth_headers response_json = JSON.parse(response.body, symbolize_names: true) - assert_equal(3, response_json.count) + assert_equal(@user.contacts.size, response_json.count) end def test_get_contact_details_by_uuid - get api_v1_registrant_contact_path(@contact.uuid), nil, @auth_headers + get api_v1_registrant_contact_path(@contact.uuid), headers: @auth_headers assert_response :ok response_json = JSON.parse(response.body, symbolize_names: true) @@ -33,21 +34,23 @@ class RegistrantApiContactsTest < ApplicationIntegrationTest end def test_root_does_not_accept_limit_higher_than_200 - get '/api/v1/registrant/contacts', { 'limit' => 400, 'offset' => 0 }, @auth_headers + get '/api/v1/registrant/contacts', params: { 'limit' => 400, 'offset' => 0 }, + headers: @auth_headers assert_equal(400, response.status) response_json = JSON.parse(response.body, symbolize_names: true) assert_equal({ errors: [{ limit: ['parameter is out of range'] }] }, response_json) end def test_root_does_not_accept_offset_lower_than_0 - get '/api/v1/registrant/contacts', { 'limit' => 200, 'offset' => "-10" }, @auth_headers + get '/api/v1/registrant/contacts', params: { 'limit' => 200, 'offset' => "-10" }, + headers: @auth_headers assert_equal(400, response.status) response_json = JSON.parse(response.body, symbolize_names: true) assert_equal({ errors: [{ offset: ['parameter is out of range'] }] }, response_json) end def test_root_returns_401_without_authorization - get '/api/v1/registrant/contacts', {}, {} + get '/api/v1/registrant/contacts' assert_equal(401, response.status) json_body = JSON.parse(response.body, symbolize_names: true) diff --git a/test/integration/api/registrant/registrant_api_cors_headers_test.rb b/test/integration/api/registrant/registrant_api_cors_headers_test.rb index 6bb768bc3..3b9fa46dc 100644 --- a/test/integration/api/registrant/registrant_api_cors_headers_test.rb +++ b/test/integration/api/registrant/registrant_api_cors_headers_test.rb @@ -2,13 +2,13 @@ require 'test_helper' class RegistrantApiCorsHeadersTest < ApplicationIntegrationTest def test_returns_200_response_code_for_options_request - options '/api/v1/registrant/auth/eid', {}, { 'Origin' => 'https://example.com' } - + process :options, api_v1_registrant_auth_eid_path, + headers: { 'Origin' => 'https://example.com' } assert_equal('200', response.code) end def test_returns_expected_headers_for_options_requests - options '/api/v1/registrant/auth/eid', {}, { 'Origin' => 'https://example.com' } + process :options, api_v1_registrant_auth_eid_path, headers: { 'Origin' => 'https://example.com' } assert_equal('https://example.com', response.headers['Access-Control-Allow-Origin']) assert_equal('POST, GET, PUT, PATCH, DELETE, OPTIONS', @@ -20,16 +20,15 @@ class RegistrantApiCorsHeadersTest < ApplicationIntegrationTest end def test_returns_empty_body - options '/api/v1/registrant/auth/eid', { 'Origin' => 'https://example.com' } - + process :options, api_v1_registrant_auth_eid_path, headers: { 'Origin' => 'https://example.com' } assert_equal('', response.body) end def test_it_returns_cors_headers_for_other_requests - post '/api/v1/registrant/auth/eid', {}, { 'Origin' => 'https://example.com' } + post '/api/v1/registrant/auth/eid', headers: { 'Origin' => 'https://example.com' } assert_equal('https://example.com', response.headers['Access-Control-Allow-Origin']) - get '/api/v1/registrant/contacts', {}, { 'Origin' => 'https://example.com' } + get '/api/v1/registrant/contacts', headers: { 'Origin' => 'https://example.com' } assert_equal('https://example.com', response.headers['Access-Control-Allow-Origin']) end end diff --git a/test/integration/api/registrant/registrant_api_domains_test.rb b/test/integration/api/registrant/registrant_api_domains_test.rb index 9095323f2..22516fecc 100644 --- a/test/integration/api/registrant/registrant_api_domains_test.rb +++ b/test/integration/api/registrant/registrant_api_domains_test.rb @@ -12,7 +12,7 @@ class RegistrantApiDomainsTest < ApplicationIntegrationTest end def test_get_domain_details_by_uuid - get '/api/v1/registrant/domains/5edda1a5-3548-41ee-8b65-6d60daf85a37', {}, @auth_headers + get '/api/v1/registrant/domains/5edda1a5-3548-41ee-8b65-6d60daf85a37', headers: @auth_headers assert_equal(200, response.status) domain = JSON.parse(response.body, symbolize_names: true) @@ -20,17 +20,25 @@ class RegistrantApiDomainsTest < ApplicationIntegrationTest assert_equal('hospital.test', domain[:name]) assert_equal('5edda1a5-3548-41ee-8b65-6d60daf85a37', domain[:id]) assert_equal({name: 'John', id: 'eb2f2766-b44c-4e14-9f16-32ab1a7cb957'}, domain[:registrant]) - assert_equal([{name: 'John', id: 'eb2f2766-b44c-4e14-9f16-32ab1a7cb957'}], + assert_equal([{name: 'John', + id: 'eb2f2766-b44c-4e14-9f16-32ab1a7cb957', + email: 'john@inbox.test'}], domain[:admin_contacts]) - assert_equal([{name: 'John', id: 'eb2f2766-b44c-4e14-9f16-32ab1a7cb957'}], + assert_equal([{name: 'John', + id: 'eb2f2766-b44c-4e14-9f16-32ab1a7cb957', + email: 'john@inbox.test'}], domain[:tech_contacts]) assert_equal({ name: 'Good Names', website: nil }, domain[:registrar]) + assert_equal([], domain[:nameservers]) + assert_equal([], domain[:dnssec_keys]) + assert(domain.has_key?(:dnssec_changed_at)) + assert(domain.has_key?(:locked_by_registrant_at)) end def test_get_non_existent_domain_details_by_uuid - get '/api/v1/registrant/domains/random-uuid', {}, @auth_headers + get '/api/v1/registrant/domains/random-uuid', headers: @auth_headers assert_equal(404, response.status) response_json = JSON.parse(response.body, symbolize_names: true) @@ -38,7 +46,7 @@ class RegistrantApiDomainsTest < ApplicationIntegrationTest end def test_root_returns_domain_list - get '/api/v1/registrant/domains', {}, @auth_headers + get '/api/v1/registrant/domains', headers: @auth_headers assert_equal(200, response.status) response_json = JSON.parse(response.body, symbolize_names: true) @@ -50,20 +58,22 @@ class RegistrantApiDomainsTest < ApplicationIntegrationTest end def test_root_accepts_limit_and_offset_parameters - get '/api/v1/registrant/domains', { 'limit' => 2, 'offset' => 0 }, @auth_headers + get '/api/v1/registrant/domains', params: { 'limit' => 2, 'offset' => 0 }, + headers: @auth_headers response_json = JSON.parse(response.body, symbolize_names: true) assert_equal(200, response.status) assert_equal(2, response_json.count) - get '/api/v1/registrant/domains', {}, @auth_headers + get '/api/v1/registrant/domains', headers: @auth_headers response_json = JSON.parse(response.body, symbolize_names: true) assert_equal(4, response_json.count) end def test_root_does_not_accept_limit_higher_than_200 - get '/api/v1/registrant/domains', { 'limit' => 400, 'offset' => 0 }, @auth_headers + get '/api/v1/registrant/domains', params: { 'limit' => 400, 'offset' => 0 }, + headers: @auth_headers assert_equal(400, response.status) response_json = JSON.parse(response.body, symbolize_names: true) @@ -71,7 +81,8 @@ class RegistrantApiDomainsTest < ApplicationIntegrationTest end def test_root_does_not_accept_offset_lower_than_0 - get '/api/v1/registrant/domains', { 'limit' => 200, 'offset' => "-10" }, @auth_headers + get '/api/v1/registrant/domains', params: { 'limit' => 200, 'offset' => "-10" }, + headers: @auth_headers assert_equal(400, response.status) response_json = JSON.parse(response.body, symbolize_names: true) @@ -79,7 +90,7 @@ class RegistrantApiDomainsTest < ApplicationIntegrationTest end def test_root_returns_401_without_authorization - get '/api/v1/registrant/domains', {}, {} + get '/api/v1/registrant/domains' assert_equal(401, response.status) json_body = JSON.parse(response.body, symbolize_names: true) @@ -87,7 +98,7 @@ class RegistrantApiDomainsTest < ApplicationIntegrationTest end def test_details_returns_401_without_authorization - get '/api/v1/registrant/domains/5edda1a5-3548-41ee-8b65-6d60daf85a37', {}, {} + get '/api/v1/registrant/domains/5edda1a5-3548-41ee-8b65-6d60daf85a37' assert_equal(401, response.status) json_body = JSON.parse(response.body, symbolize_names: true) diff --git a/test/integration/api/registrant/registrant_api_registry_locks_test.rb b/test/integration/api/registrant/registrant_api_registry_locks_test.rb index 049345fb5..fb6d13aca 100644 --- a/test/integration/api/registrant/registrant_api_registry_locks_test.rb +++ b/test/integration/api/registrant/registrant_api_registry_locks_test.rb @@ -12,7 +12,7 @@ class RegistrantApiRegistryLocksTest < ApplicationIntegrationTest def test_can_lock_a_not_locked_domain post '/api/v1/registrant/domains/2df2c1a1-8f6a-490a-81be-8bdf29866880/registry_lock', - {}, @auth_headers + headers: @auth_headers response_json = JSON.parse(response.body, symbolize_names: true) @@ -27,7 +27,7 @@ class RegistrantApiRegistryLocksTest < ApplicationIntegrationTest def test_locking_a_domain_creates_a_version_record assert_difference '@domain.versions.count', 1 do post '/api/v1/registrant/domains/2df2c1a1-8f6a-490a-81be-8bdf29866880/registry_lock', - {}, @auth_headers + headers: @auth_headers end @domain.reload @@ -39,7 +39,7 @@ class RegistrantApiRegistryLocksTest < ApplicationIntegrationTest @domain.save post '/api/v1/registrant/domains/2df2c1a1-8f6a-490a-81be-8bdf29866880/registry_lock', - {}, @auth_headers + headers: @auth_headers response_json = JSON.parse(response.body, symbolize_names: true) assert_equal(422, response.status) @@ -51,7 +51,7 @@ class RegistrantApiRegistryLocksTest < ApplicationIntegrationTest assert(@domain.locked_by_registrant?) post '/api/v1/registrant/domains/2df2c1a1-8f6a-490a-81be-8bdf29866880/registry_lock', - {}, @auth_headers + headers: @auth_headers response_json = JSON.parse(response.body, symbolize_names: true) assert_equal(422, response.status) @@ -62,7 +62,7 @@ class RegistrantApiRegistryLocksTest < ApplicationIntegrationTest @domain.apply_registry_lock delete '/api/v1/registrant/domains/2df2c1a1-8f6a-490a-81be-8bdf29866880/registry_lock', - {}, @auth_headers + headers: @auth_headers response_json = JSON.parse(response.body, symbolize_names: true) assert(response_json[:statuses].include?(DomainStatus::OK)) @@ -73,7 +73,7 @@ class RegistrantApiRegistryLocksTest < ApplicationIntegrationTest def test_cannot_unlock_a_not_locked_domain delete '/api/v1/registrant/domains/2df2c1a1-8f6a-490a-81be-8bdf29866880/registry_lock', - {}, @auth_headers + headers: @auth_headers response_json = JSON.parse(response.body, symbolize_names: true) assert_equal(422, response.status) @@ -81,8 +81,7 @@ class RegistrantApiRegistryLocksTest < ApplicationIntegrationTest end def test_returns_404_when_domain_is_not_found - post '/api/v1/registrant/domains/random-uuid/registry_lock', - {}, @auth_headers + post '/api/v1/registrant/domains/random-uuid/registry_lock', headers: @auth_headers response_json = JSON.parse(response.body, symbolize_names: true) assert_equal(404, response.status) @@ -99,7 +98,7 @@ class RegistrantApiRegistryLocksTest < ApplicationIntegrationTest assert_equal '1234', contact.ident assert_equal 'US', contact.ident_country_code - post api_v1_registrant_domain_registry_lock_path(domain.uuid), nil, @auth_headers + post api_v1_registrant_domain_registry_lock_path(domain.uuid), headers: @auth_headers assert_response :unauthorized response_json = JSON.parse(response.body, symbolize_names: true) @@ -109,7 +108,7 @@ class RegistrantApiRegistryLocksTest < ApplicationIntegrationTest def test_registrant_can_lock_a_domain post '/api/v1/registrant/domains/1b3ee442-e8fe-4922-9492-8fcb9dccc69c/registry_lock', - {}, @auth_headers + headers: @auth_headers assert_equal(200, response.status) response_json = JSON.parse(response.body, symbolize_names: true) @@ -125,16 +124,25 @@ class RegistrantApiRegistryLocksTest < ApplicationIntegrationTest assert_equal 'https://bestnames.test', @domain.registrar.website post '/api/v1/registrant/domains/1b3ee442-e8fe-4922-9492-8fcb9dccc69c/registry_lock', - {}, @auth_headers + headers: @auth_headers assert_equal(200, response.status) response_json = JSON.parse(response.body, symbolize_names: true) assert_equal({ name: 'Best Names', website: 'https://bestnames.test' }, response_json[:registrar]) assert_equal({name: 'John', id: 'eb2f2766-b44c-4e14-9f16-32ab1a7cb957'}, response_json[:registrant]) - assert_equal([{name: 'Jane', id: '9db3de62-2414-4487-bee2-d5c155567768'}], response_json[:admin_contacts]) - assert_equal([{name: 'William', id: '0aa54704-d6f7-4ca9-b8ca-2827d9a4e4eb'}, - {name: 'Acme Ltd', id: 'f1dd365c-5be9-4b3d-a44e-3fa002465e4d'}].to_set, + assert_equal([{name: 'Jane', + id: '9db3de62-2414-4487-bee2-d5c155567768', + email: 'jane@mail.test' + }], + response_json[:admin_contacts]) + assert_equal([{name: 'William', + id: '0aa54704-d6f7-4ca9-b8ca-2827d9a4e4eb', + email: 'william@inbox.test'}, + {name: 'Acme Ltd', + id: 'f1dd365c-5be9-4b3d-a44e-3fa002465e4d', + email: 'acme@outlook.test' + }].to_set, response_json[:tech_contacts].to_set) assert_equal( [{hostname: 'ns1.bestnames.test', ipv4: ['192.0.2.1'], ipv6: ['2001:db8::1']}, diff --git a/test/integration/api/v1/auctions/details_test.rb b/test/integration/api/v1/auctions/details_test.rb index 996151cee..374051258 100644 --- a/test/integration/api/v1/auctions/details_test.rb +++ b/test/integration/api/v1/auctions/details_test.rb @@ -15,18 +15,21 @@ class ApiV1AuctionDetailsTest < ActionDispatch::IntegrationTest assert_equal 'auction.test', @auction.domain assert_equal Auction.statuses[:no_bids], @auction.status - get api_v1_auction_path(@auction.uuid), nil, 'Content-Type' => Mime::JSON.to_s + get api_v1_auction_path(@auction.uuid), as: :json assert_response :ok assert_equal ({ 'id' => '1b3ee442-e8fe-4922-9492-8fcb9dccc69c', 'domain' => 'auction.test', 'status' => Auction.statuses[:no_bids] }), ActiveSupport::JSON - .decode(response.body) + .decode(response.body) end def test_auction_not_found - assert_raises ActiveRecord::RecordNotFound do - get api_v1_auction_path('non-existing-uuid'), nil, 'Content-Type' => Mime::JSON.to_s - end + expected_uuid = 'not-a-real-path' + get api_v1_auction_path(expected_uuid), as: :json + assert_response :not_found + json = JSON.parse(response.body, symbolize_names: true) + assert_equal expected_uuid, json[:uuid] + assert_equal 'Not Found', json[:error] end -end \ No newline at end of file +end diff --git a/test/integration/api/v1/auctions/list_test.rb b/test/integration/api/v1/auctions/list_test.rb index 3dfaff39e..ae3f4338f 100644 --- a/test/integration/api/v1/auctions/list_test.rb +++ b/test/integration/api/v1/auctions/list_test.rb @@ -10,19 +10,19 @@ class ApiV1AuctionListTest < ActionDispatch::IntegrationTest domain: 'auction.test', status: Auction.statuses[:started]) - get api_v1_auctions_path, nil, 'Content-Type' => Mime::JSON.to_s + get api_v1_auctions_path, as: :json assert_response :ok assert_equal ([{ 'id' => '1b3ee442-e8fe-4922-9492-8fcb9dccc69c', 'domain' => 'auction.test', 'status' => Auction.statuses[:started] }]), ActiveSupport::JSON - .decode(response.body) + .decode(response.body) end def test_does_not_return_finished_auctions @auction.update!(domain: 'auction.test', status: Auction.statuses[:awaiting_payment]) - get api_v1_auctions_path, nil, 'Content-Type' => Mime::JSON.to_s + get api_v1_auctions_path, as: :json assert_response :ok assert_empty ActiveSupport::JSON.decode(response.body) diff --git a/test/integration/api/v1/auctions/update_test.rb b/test/integration/api/v1/auctions/update_test.rb index 64b3a92f5..5b00a1052 100644 --- a/test/integration/api/v1/auctions/update_test.rb +++ b/test/integration/api/v1/auctions/update_test.rb @@ -20,47 +20,64 @@ class ApiV1AuctionUpdateTest < ActionDispatch::IntegrationTest assert_equal '1b3ee442-e8fe-4922-9492-8fcb9dccc69c', @auction.uuid assert_equal 'auction.test', @auction.domain - patch api_v1_auction_path(@auction.uuid), { status: Auction.statuses[:awaiting_payment] } - .to_json, 'Content-Type' => Mime::JSON.to_s + patch api_v1_auction_path(@auction.uuid), + params: { status: Auction.statuses[:awaiting_payment] }, + as: :json assert_response :ok assert_equal ({ 'id' => '1b3ee442-e8fe-4922-9492-8fcb9dccc69c', 'domain' => 'auction.test', 'status' => Auction.statuses[:awaiting_payment] }), ActiveSupport::JSON - .decode(response.body) + .decode(response.body) end def test_marks_as_awaiting_payment - patch api_v1_auction_path(@auction.uuid), { status: Auction.statuses[:awaiting_payment] } - .to_json, 'Content-Type' => Mime::JSON.to_s + patch api_v1_auction_path(@auction.uuid), + params: { status: Auction.statuses[:awaiting_payment] }, + as: :json @auction.reload assert @auction.awaiting_payment? end + def test_sets_registration_deadline + deadline = (Time.zone.now + 10.days).end_of_day + patch api_v1_auction_path(@auction.uuid), + params: { status: Auction.statuses[:awaiting_payment], + registration_deadline: deadline}, + as: :json + @auction.reload + + assert_in_delta @auction.registration_deadline, deadline, 1.second + end + def test_marks_as_no_bids - patch api_v1_auction_path(@auction.uuid), { status: Auction.statuses[:no_bids] } - .to_json, 'Content-Type' => Mime::JSON.to_s + patch api_v1_auction_path(@auction.uuid), + params: { status: Auction.statuses[:no_bids] }, + as: :json @auction.reload assert @auction.no_bids? end def test_marks_as_payment_received - patch api_v1_auction_path(@auction.uuid), { status: Auction.statuses[:payment_received] } - .to_json, 'Content-Type' => Mime::JSON.to_s + patch api_v1_auction_path(@auction.uuid), + params: { status: Auction.statuses[:payment_received] }, + as: :json @auction.reload assert @auction.payment_received? end def test_marks_as_payment_not_received - patch api_v1_auction_path(@auction.uuid), { status: Auction.statuses[:payment_not_received] } - .to_json, 'Content-Type' => Mime::JSON.to_s + patch api_v1_auction_path(@auction.uuid), + params: { status: Auction.statuses[:payment_not_received] }, + as: :json @auction.reload assert @auction.payment_not_received? end def test_marks_as_domain_not_registered - patch api_v1_auction_path(@auction.uuid), { status: Auction.statuses[:domain_not_registered] } - .to_json, 'Content-Type' => Mime::JSON.to_s + patch api_v1_auction_path(@auction.uuid), + params: { status: Auction.statuses[:domain_not_registered] }, + as: :json @auction.reload assert @auction.domain_not_registered? end @@ -69,8 +86,9 @@ class ApiV1AuctionUpdateTest < ActionDispatch::IntegrationTest @auction.update!(registration_code: 'auction-001', status: Auction.statuses[:awaiting_payment]) - patch api_v1_auction_path(@auction.uuid), { status: Auction.statuses[:payment_received] } - .to_json, 'Content-Type' => Mime::JSON.to_s + patch api_v1_auction_path(@auction.uuid), + params: { status: Auction.statuses[:payment_received] }, + as: :json response_json = ActiveSupport::JSON.decode(response.body) assert_not_nil response_json['registration_code'] @@ -79,8 +97,9 @@ class ApiV1AuctionUpdateTest < ActionDispatch::IntegrationTest def test_conceals_registration_code_when_payment_is_not_received @auction.update!(status: Auction.statuses[:awaiting_payment]) - patch api_v1_auction_path(@auction.uuid), { status: Auction.statuses[:payment_not_received] } - .to_json, 'Content-Type' => Mime::JSON.to_s + patch api_v1_auction_path(@auction.uuid), + params: { status: Auction.statuses[:payment_not_received] }, + as: :json response_json = ActiveSupport::JSON.decode(response.body) assert_nil response_json['registration_code'] @@ -91,8 +110,9 @@ class ApiV1AuctionUpdateTest < ActionDispatch::IntegrationTest assert_equal 'auction.test', @auction.domain @whois_record.update!(updated_at: '2010-07-04') - patch api_v1_auction_path(@auction.uuid), { status: Auction.statuses[:payment_received] } - .to_json, 'Content-Type' => Mime::JSON.to_s + patch api_v1_auction_path(@auction.uuid), + params: { status: Auction.statuses[:payment_received] }, + as: :json @whois_record.reload assert_equal Time.zone.parse('2010-07-05 10:00'), @whois_record.updated_at @@ -103,8 +123,9 @@ class ApiV1AuctionUpdateTest < ActionDispatch::IntegrationTest assert_equal 'auction.test', @auction.domain @whois_record.delete - patch api_v1_auction_path(@auction.uuid), { status: Auction.statuses[:payment_received] } - .to_json, 'Content-Type' => Mime::JSON.to_s + patch api_v1_auction_path(@auction.uuid), + params: { status: Auction.statuses[:payment_received] }, + as: :json new_whois_record = Whois::Record.find_by(name: @auction.domain) assert_equal Time.zone.parse('2010-07-05 10:00'), new_whois_record.updated_at @@ -114,16 +135,20 @@ class ApiV1AuctionUpdateTest < ActionDispatch::IntegrationTest def test_inaccessible_when_ip_address_is_not_allowed ENV['auction_api_allowed_ips'] = '' - patch api_v1_auction_path(@auction.uuid), { status: 'any' }.to_json, - 'Content-Type' => Mime::JSON.to_s + patch api_v1_auction_path(@auction.uuid), params: { status: 'any' }, as: :json assert_response :unauthorized end def test_auction_not_found - assert_raises ActiveRecord::RecordNotFound do - patch api_v1_auction_path('non-existing-uuid'), { status: Auction.statuses[:no_bids] }.to_json, - 'Content-Type' => Mime::JSON.to_s - end + expected_uuid = 'non-existing-uuid' + patch api_v1_auction_path(expected_uuid), + params: { status: Auction.statuses[:no_bids] }, + as: :json + + assert_response :not_found + json = JSON.parse(response.body, symbolize_names: true) + assert_equal expected_uuid, json[:uuid] + assert_equal 'Not Found', json[:error] end end diff --git a/test/integration/api/v1/registrant/contacts/details_test.rb b/test/integration/api/v1/registrant/contacts/details_test.rb index 073c8e2b8..0352ade8d 100644 --- a/test/integration/api/v1/registrant/contacts/details_test.rb +++ b/test/integration/api/v1/registrant/contacts/details_test.rb @@ -14,8 +14,8 @@ class RegistrantApiV1ContactDetailsTest < ActionDispatch::IntegrationTest end def test_returns_contact_details - get api_v1_registrant_contact_path(@contact.uuid), nil, 'HTTP_AUTHORIZATION' => auth_token, - 'Content-Type' => Mime::JSON.to_s + get api_v1_registrant_contact_path(@contact.uuid), as: :json, + headers: { 'HTTP_AUTHORIZATION' => auth_token } assert_response :ok assert_equal ({ id: @contact.uuid, @@ -43,8 +43,8 @@ class RegistrantApiV1ContactDetailsTest < ActionDispatch::IntegrationTest end def test_non_existent_contact - get api_v1_registrant_contact_path('non-existent'), nil, 'HTTP_AUTHORIZATION' => auth_token, - 'Content-Type' => Mime::JSON.to_s + get api_v1_registrant_contact_path('non-existent'), as: :json, + headers: { 'HTTP_AUTHORIZATION' => auth_token } assert_response :not_found assert_equal({ errors: [base: ['Contact not found']] }, JSON.parse(response.body, @@ -52,7 +52,7 @@ class RegistrantApiV1ContactDetailsTest < ActionDispatch::IntegrationTest end def test_anonymous_user - get api_v1_registrant_contact_path(@contact.uuid), nil, 'Content-Type' => Mime::JSON.to_s + get api_v1_registrant_contact_path(@contact.uuid) assert_response :unauthorized assert_equal({ errors: [base: ['Not authorized']] }, JSON.parse(response.body, @@ -66,8 +66,8 @@ class RegistrantApiV1ContactDetailsTest < ActionDispatch::IntegrationTest assert_equal 'US-1234', @user.registrant_ident CompanyRegister::Client.stub(:new, CompanyRegisterClientStub.new) do - get api_v1_registrant_contact_path(@contact.uuid), nil, 'HTTP_AUTHORIZATION' => auth_token, - 'Content-Type' => Mime::JSON.to_s + get api_v1_registrant_contact_path(@contact.uuid), as: :json, + headers: { 'HTTP_AUTHORIZATION' => auth_token } end response_json = JSON.parse(response.body, symbolize_names: true) @@ -75,11 +75,14 @@ class RegistrantApiV1ContactDetailsTest < ActionDispatch::IntegrationTest end def test_unmanaged_contact_cannot_be_accessed - assert_equal 'US-1234', @user.registrant_ident - @contact.update!(ident: '12345') + @user.update!(registrant_ident: 'US-12345') + @contact.update!(ident: '12345879') + companies = Contact.where(ident_type: 'org') + companies.update_all(ident: '78964521') + companies.reload - get api_v1_registrant_contact_path(@contact.uuid), nil, 'HTTP_AUTHORIZATION' => auth_token, - 'Content-Type' => Mime::JSON.to_s + get api_v1_registrant_contact_path(@contact.uuid), as: :json, + headers: { 'HTTP_AUTHORIZATION' => auth_token } assert_response :not_found response_json = JSON.parse(response.body, symbolize_names: true) @@ -93,4 +96,4 @@ class RegistrantApiV1ContactDetailsTest < ActionDispatch::IntegrationTest hash = token_creator.token_in_hash "Bearer #{hash[:access_token]}" end -end \ No newline at end of file +end diff --git a/test/integration/api/v1/registrant/contacts/list_test.rb b/test/integration/api/v1/registrant/contacts/list_test.rb index 36b5cf6e3..a42aca694 100644 --- a/test/integration/api/v1/registrant/contacts/list_test.rb +++ b/test/integration/api/v1/registrant/contacts/list_test.rb @@ -20,8 +20,7 @@ class RegistrantApiV1ContactListTest < ActionDispatch::IntegrationTest assert_equal 'US', @contact.ident_country_code assert_equal 'US-1234', @user.registrant_ident - get api_v1_registrant_contacts_path, nil, 'HTTP_AUTHORIZATION' => auth_token, - 'Content-Type' => Mime::JSON.to_s + get api_v1_registrant_contacts_path, as: :json, headers: { 'HTTP_AUTHORIZATION' => auth_token } response_json = JSON.parse(response.body, symbolize_names: true) assert_equal 1, response_json.size @@ -33,12 +32,11 @@ class RegistrantApiV1ContactListTest < ActionDispatch::IntegrationTest @contact = contacts(:acme_ltd) assert_equal 'acme-ltd-001', @contact.code - get api_v1_registrant_contacts_path, nil, 'HTTP_AUTHORIZATION' => auth_token, - 'Content-Type' => Mime::JSON.to_s + get api_v1_registrant_contacts_path, as: :json, headers: { 'HTTP_AUTHORIZATION' => auth_token } response_json = JSON.parse(response.body, symbolize_names: true) - assert_equal 1, response_json.size - assert_equal 'acme-ltd-001', response_json.first[:code] + assert_equal @user.contacts.count, response_json.size + assert_includes response_json.map{ |hash| hash[:code] }, @contact.code end def test_returns_direct_contacts_when_company_register_is_unavailable @@ -48,8 +46,8 @@ class RegistrantApiV1ContactListTest < ActionDispatch::IntegrationTest assert_equal 'US-1234', @user.registrant_ident CompanyRegister::Client.stub(:new, CompanyRegisterClientStub.new) do - get api_v1_registrant_contacts_path, nil, 'HTTP_AUTHORIZATION' => auth_token, - 'Content-Type' => Mime::JSON.to_s + get api_v1_registrant_contacts_path, as: :json, + headers: { 'HTTP_AUTHORIZATION' => auth_token } end response_json = JSON.parse(response.body, symbolize_names: true) @@ -72,4 +70,4 @@ class RegistrantApiV1ContactListTest < ActionDispatch::IntegrationTest hash = token_creator.token_in_hash "Bearer #{hash[:access_token]}" end -end \ No newline at end of file +end diff --git a/test/integration/api/v1/registrant/contacts/update_test.rb b/test/integration/api/v1/registrant/contacts/update_test.rb index d87b787f0..4ddf8b0ff 100644 --- a/test/integration/api/v1/registrant/contacts/update_test.rb +++ b/test/integration/api/v1/registrant/contacts/update_test.rb @@ -5,14 +5,14 @@ class RegistrantApiV1ContactUpdateTest < ActionDispatch::IntegrationTest setup do @contact = contacts(:john) - @original_address_processing_setting = Setting.address_processing + @original_address_processing = Setting.address_processing @original_fax_enabled_setting = ENV['fax_enabled'] @user = users(:registrant) end teardown do - Setting.address_processing = @original_address_processing_setting + Setting.address_processing = @original_address_processing ENV['fax_enabled'] = @original_fax_enabled_setting end @@ -21,12 +21,11 @@ class RegistrantApiV1ContactUpdateTest < ActionDispatch::IntegrationTest email: 'john@shop.test', phone: '+111.1') - patch api_v1_registrant_contact_path(@contact.uuid), { name: 'William', - email: 'william@shop.test', - phone: '+222.2' }.to_json, - 'HTTP_AUTHORIZATION' => auth_token, - 'Accept' => Mime::JSON, - 'Content-Type' => Mime::JSON.to_s + patch api_v1_registrant_contact_path(@contact.uuid), params: { name: 'William', + email: 'william@shop.test', + phone: '+222.2' }, + as: :json, + headers: { 'HTTP_AUTHORIZATION' => auth_token } assert_response :ok @contact.reload @@ -37,10 +36,9 @@ class RegistrantApiV1ContactUpdateTest < ActionDispatch::IntegrationTest def test_notify_registrar assert_difference -> { @contact.registrar.notifications.count } do - patch api_v1_registrant_contact_path(@contact.uuid), { name: 'new name' }.to_json, - 'HTTP_AUTHORIZATION' => auth_token, - 'Accept' => Mime::JSON, - 'Content-Type' => Mime::JSON.to_s + patch api_v1_registrant_contact_path(@contact.uuid), params: { name: 'new name' }, + as: :json, + headers: { 'HTTP_AUTHORIZATION' => auth_token } end notification = @contact.registrar.notifications.last assert_equal 'Contact john-001 has been updated by registrant', notification.text @@ -50,10 +48,9 @@ class RegistrantApiV1ContactUpdateTest < ActionDispatch::IntegrationTest @contact.update!(fax: '+666.6') ENV['fax_enabled'] = 'true' - patch api_v1_registrant_contact_path(@contact.uuid), { fax: '+777.7' }.to_json, - 'HTTP_AUTHORIZATION' => auth_token, - 'Accept' => Mime::JSON, - 'Content-Type' => Mime::JSON.to_s + patch api_v1_registrant_contact_path(@contact.uuid), params: { fax: '+777.7' }, + as: :json, + headers: { 'HTTP_AUTHORIZATION' => auth_token } assert_response :ok @contact.reload @@ -63,10 +60,9 @@ class RegistrantApiV1ContactUpdateTest < ActionDispatch::IntegrationTest def test_fax_cannot_be_updated_when_disabled ENV['fax_enabled'] = 'false' - patch api_v1_registrant_contact_path(@contact.uuid), { fax: '+823.7' }.to_json, - 'HTTP_AUTHORIZATION' => auth_token, - 'Accept' => Mime::JSON, - 'Content-Type' => Mime::JSON.to_s + patch api_v1_registrant_contact_path(@contact.uuid), params: { fax: '+823.7' }, + as: :json, + headers: { 'HTTP_AUTHORIZATION' => auth_token } assert_response :bad_request @contact.reload @@ -80,14 +76,13 @@ class RegistrantApiV1ContactUpdateTest < ActionDispatch::IntegrationTest def test_update_address_when_enabled Setting.address_processing = true - patch api_v1_registrant_contact_path(@contact.uuid), { address: { city: 'new city', - street: 'new street', - zip: '92837', - country_code: 'RU', - state: 'new state' } }.to_json, - 'HTTP_AUTHORIZATION' => auth_token, - 'Accept' => Mime::JSON, - 'Content-Type' => Mime::JSON.to_s + patch api_v1_registrant_contact_path(@contact.uuid), params: { address: { city: 'new city', + street: 'new street', + zip: '92837', + country_code: 'RU', + state: 'new state' } }, + as: :json, + headers: { 'HTTP_AUTHORIZATION' => auth_token } assert_response :ok @contact.reload @@ -96,13 +91,12 @@ class RegistrantApiV1ContactUpdateTest < ActionDispatch::IntegrationTest end def test_address_is_optional_when_enabled - @contact.update!(street: 'any', zip: 'any', city: 'any', state: 'any', country_code: 'US') Setting.address_processing = true + @contact.update!(street: 'any', zip: 'any', city: 'any', state: 'any', country_code: 'US') - patch api_v1_registrant_contact_path(@contact.uuid), { name: 'any' }.to_json, - 'HTTP_AUTHORIZATION' => auth_token, - 'Accept' => Mime::JSON, - 'Content-Type' => Mime::JSON.to_s + patch api_v1_registrant_contact_path(@contact.uuid), params: { name: 'any' }, + as: :json, + headers: { 'HTTP_AUTHORIZATION' => auth_token } assert_response :ok end @@ -111,11 +105,10 @@ class RegistrantApiV1ContactUpdateTest < ActionDispatch::IntegrationTest @contact.update!(street: 'old street') Setting.address_processing = false - patch api_v1_registrant_contact_path(@contact.uuid), { address: { street: 'new street' } } - .to_json, - 'HTTP_AUTHORIZATION' => auth_token, - 'Accept' => Mime::JSON, - 'Content-Type' => Mime::JSON.to_s + patch api_v1_registrant_contact_path(@contact.uuid), + params: { address: { street: 'new street' } }, + as: :json, + headers: { 'HTTP_AUTHORIZATION' => auth_token } @contact.reload assert_response :bad_request @@ -130,10 +123,10 @@ class RegistrantApiV1ContactUpdateTest < ActionDispatch::IntegrationTest @contact.update!(ident_type: Contact::PRIV, disclosed_attributes: %w[]) - patch api_v1_registrant_contact_path(@contact.uuid), { disclosed_attributes: %w[name] }.to_json, - 'HTTP_AUTHORIZATION' => auth_token, - 'Accept' => Mime::JSON, - 'Content-Type' => Mime::JSON.to_s + patch api_v1_registrant_contact_path(@contact.uuid), + params: { disclosed_attributes: %w[name] }, + as: :json, + headers: { 'HTTP_AUTHORIZATION' => auth_token } @contact.reload assert_response :ok @@ -143,10 +136,10 @@ class RegistrantApiV1ContactUpdateTest < ActionDispatch::IntegrationTest def test_conceal_private_persons_data @contact.update!(ident_type: Contact::PRIV, disclosed_attributes: %w[name]) - patch api_v1_registrant_contact_path(@contact.uuid), { disclosed_attributes: [] }.to_json, - { 'HTTP_AUTHORIZATION' => auth_token, - 'Accept' => Mime::JSON, - 'Content-Type' => Mime::JSON.to_s } + patch api_v1_registrant_contact_path(@contact.uuid), + params: { disclosed_attributes: [] }, + as: :json, + headers: { 'HTTP_AUTHORIZATION' => auth_token } @contact.reload @@ -166,11 +159,10 @@ class RegistrantApiV1ContactUpdateTest < ActionDispatch::IntegrationTest assert_equal 'US-1234', @user.registrant_ident assert_no_changes -> { @contact.disclosed_attributes } do - patch api_v1_registrant_contact_path(@contact.uuid), { disclosed_attributes: %w[name] } - .to_json, - 'HTTP_AUTHORIZATION' => auth_token, - 'Accept' => Mime::JSON, - 'Content-Type' => Mime::JSON.to_s + patch api_v1_registrant_contact_path(@contact.uuid), + params: { disclosed_attributes: %w[name] }, + as: :json, + headers: { 'HTTP_AUTHORIZATION' => auth_token } @contact.reload end assert_response :bad_request @@ -182,10 +174,9 @@ class RegistrantApiV1ContactUpdateTest < ActionDispatch::IntegrationTest end def test_return_contact_details - patch api_v1_registrant_contact_path(@contact.uuid), { name: 'new name' }.to_json, - 'HTTP_AUTHORIZATION' => auth_token, - 'Accept' => Mime::JSON, - 'Content-Type' => Mime::JSON.to_s + patch api_v1_registrant_contact_path(@contact.uuid), params: { name: 'new name' }, + as: :json, + headers: { 'HTTP_AUTHORIZATION' => auth_token } assert_equal ({ id: @contact.uuid, name: 'new name', code: @contact.code, @@ -211,10 +202,9 @@ class RegistrantApiV1ContactUpdateTest < ActionDispatch::IntegrationTest end def test_errors - patch api_v1_registrant_contact_path(@contact.uuid), { phone: 'invalid' }.to_json, - 'HTTP_AUTHORIZATION' => auth_token, - 'Accept' => Mime::JSON, - 'Content-Type' => Mime::JSON.to_s + patch api_v1_registrant_contact_path(@contact.uuid), params: { phone: 'invalid' }, + as: :json, + headers: { 'HTTP_AUTHORIZATION' => auth_token } assert_response :bad_request assert_equal ({ errors: { phone: ['Phone nr is invalid'] } }), JSON.parse(response.body, @@ -224,11 +214,13 @@ class RegistrantApiV1ContactUpdateTest < ActionDispatch::IntegrationTest def test_unmanaged_contact_cannot_be_updated assert_equal 'US-1234', @user.registrant_ident @contact.update!(ident: '12345') + companies = Contact.where(ident_type: 'org') + companies.update_all(ident: '78964521') + companies.reload - patch api_v1_registrant_contact_path(@contact.uuid), { name: 'new name' }.to_json, - 'HTTP_AUTHORIZATION' => auth_token, - 'Accept' => Mime::JSON, - 'Content-Type' => Mime::JSON.to_s + patch api_v1_registrant_contact_path(@contact.uuid), params: { name: 'new name' }, + as: :json, + headers: { 'HTTP_AUTHORIZATION' => auth_token } @contact.reload assert_response :not_found @@ -236,7 +228,8 @@ class RegistrantApiV1ContactUpdateTest < ActionDispatch::IntegrationTest end def test_non_existent_contact - patch api_v1_registrant_contact_path('non-existent'), nil, 'HTTP_AUTHORIZATION' => auth_token + patch api_v1_registrant_contact_path('non-existent'), + headers: { 'HTTP_AUTHORIZATION' => auth_token } assert_response :not_found assert_equal ({ errors: [{ base: ['Not found'] }] }), JSON.parse(response.body, symbolize_names: true) diff --git a/test/integration/contact/audit_log_test.rb b/test/integration/contact/audit_log_test.rb index f0f6a4bf2..41699d595 100644 --- a/test/integration/contact/audit_log_test.rb +++ b/test/integration/contact/audit_log_test.rb @@ -5,7 +5,7 @@ class ContactAuditLogTest < ActionDispatch::IntegrationTest contact = contacts(:john) contact.legal_document_id = 1 - assert_difference 'contact.versions.count' do + assert_difference 'contact.versions.count', 1 do contact.save! end @@ -13,4 +13,4 @@ class ContactAuditLogTest < ActionDispatch::IntegrationTest assert_equal ({ legal_documents: [1] }).with_indifferent_access, contact_version.children.with_indifferent_access end -end \ No newline at end of file +end diff --git a/test/integration/domain/audit_log_test.rb b/test/integration/domain/audit_log_test.rb index 292994ca3..a17fded0d 100644 --- a/test/integration/domain/audit_log_test.rb +++ b/test/integration/domain/audit_log_test.rb @@ -14,7 +14,7 @@ class DomainAuditLogTest < ActionDispatch::IntegrationTest assert_equal registrant_id, domain.registrant_id domain.legal_document_id = legal_document_id - assert_difference 'domain.versions.count' do + assert_difference 'domain.versions.count', 1 do domain.save! end @@ -26,4 +26,4 @@ class DomainAuditLogTest < ActionDispatch::IntegrationTest assert_equal [legal_document_id], domain_version.children['legal_documents'] assert_equal [registrant_id], domain_version.children['registrant'] end -end \ No newline at end of file +end diff --git a/test/integration/epp/base_test.rb b/test/integration/epp/base_test.rb new file mode 100644 index 000000000..456e7b41e --- /dev/null +++ b/test/integration/epp/base_test.rb @@ -0,0 +1,98 @@ +require 'test_helper' + +class DummyEppController < Epp::BaseController + def internal_error + raise StandardError + end +end + +class EppBaseTest < EppTestCase + def test_internal_error + Rails.application.routes.draw do + post 'epp/command/internal_error', to: 'dummy_epp#internal_error', + constraints: EppConstraint.new(:poll) + end + + begin + assert_difference 'ApiLog::EppLog.count' do + post '/epp/command/internal_error', params: { frame: valid_request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + end + assert_epp_response :command_failed + rescue + raise + ensure + Rails.application.reload_routes! + end + end + + def test_validates_request_xml + invalid_xml = <<-XML + + + + XML + post valid_command_path, params: { frame: invalid_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + + assert_epp_response :syntax_error + end + + def test_anonymous_user + xml_of_epp_command_that_requires_authentication = <<-XML + + + + + + #{domains(:shop).name} + + + + + XML + post epp_info_path, params: { frame: xml_of_epp_command_that_requires_authentication }, + headers: { 'HTTP_COOKIE' => 'session=non-existent' } + + assert_epp_response :authorization_error + end + + def test_non_authorized_user + session = epp_sessions(:api_bestnames) + user = session.user + user.update!(roles: [ApiUser::BILLING]) + assert user.cannot?(:info, Domain) + + xml_of_epp_command_that_requires_authorization = <<-XML + + + + + + #{domains(:shop).name} + + + + + XML + post epp_info_path, params: { frame: xml_of_epp_command_that_requires_authorization }, + headers: { 'HTTP_COOKIE' => "session=#{session.session_id}" } + + assert_epp_response :authorization_error + end + + private + + def valid_command_path + epp_poll_path + end + + def valid_request_xml + <<-XML + + + + + XML + end +end diff --git a/test/integration/epp/contact/base_test.rb b/test/integration/epp/contact/base_test.rb new file mode 100644 index 000000000..79bb8579c --- /dev/null +++ b/test/integration/epp/contact/base_test.rb @@ -0,0 +1,22 @@ +require 'test_helper' + +class EppContactBaseTest < EppTestCase + def test_non_existent_contact + request_xml = <<-XML + + + + + + non-existent + + + + + XML + post epp_info_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + + assert_epp_response :object_does_not_exist + end +end diff --git a/test/integration/epp/contact/check/base_test.rb b/test/integration/epp/contact/check/base_test.rb index 0035f0db5..528d69d86 100644 --- a/test/integration/epp/contact/check/base_test.rb +++ b/test/integration/epp/contact/check/base_test.rb @@ -1,6 +1,6 @@ require 'test_helper' -class EppContactCheckBaseTest < ActionDispatch::IntegrationTest +class EppContactCheckBaseTest < EppTestCase setup do @contact = contacts(:john) end @@ -21,11 +21,11 @@ class EppContactCheckBaseTest < ActionDispatch::IntegrationTest XML - post '/epp/command/check', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_check_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } response_xml = Nokogiri::XML(response.body) - assert_equal '1000', response_xml.at_css('result')[:code] - assert_equal 1, response_xml.css('result').size + assert_epp_response :completed_successfully assert_equal 'john-001', response_xml.at_xpath('//contact:id', contact: xml_schema).text end @@ -43,7 +43,8 @@ class EppContactCheckBaseTest < ActionDispatch::IntegrationTest XML - post '/epp/command/check', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_check_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } response_xml = Nokogiri::XML(response.body) assert_equal '1', response_xml.at_xpath('//contact:id', contact: xml_schema)['avail'] @@ -66,7 +67,8 @@ class EppContactCheckBaseTest < ActionDispatch::IntegrationTest XML - post '/epp/command/check', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_check_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } response_xml = Nokogiri::XML(response.body) assert_equal '0', response_xml.at_xpath('//contact:id', contact: xml_schema)['avail'] @@ -89,7 +91,8 @@ class EppContactCheckBaseTest < ActionDispatch::IntegrationTest XML - post '/epp/command/check', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_check_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } response_xml = Nokogiri::XML(response.body) assert_equal 3, response_xml.xpath('//contact:cd', contact: xml_schema).size diff --git a/test/integration/epp/contact/create/base_test.rb b/test/integration/epp/contact/create/base_test.rb index ce8cad680..262487a1e 100644 --- a/test/integration/epp/contact/create/base_test.rb +++ b/test/integration/epp/contact/create/base_test.rb @@ -1,7 +1,11 @@ require 'test_helper' -class EppContactCreateBaseTest < ActionDispatch::IntegrationTest - def test_creates_new_contact_with_minimum_required_parameters +class EppContactCreateBaseTest < EppTestCase + def test_creates_new_contact_with_required_attributes + name = 'new' + email = 'new@registrar.test' + phone = '+1.2' + request_xml = <<-XML @@ -9,7 +13,113 @@ class EppContactCreateBaseTest < ActionDispatch::IntegrationTest - New + #{name} + + #{phone} + #{email} + + + + + any + + + + + XML + + assert_difference 'Contact.count' do + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + end + + assert_epp_response :completed_successfully + contact = Contact.find_by(name: name) + assert_equal name, contact.name + assert_equal email, contact.email + assert_equal phone, contact.phone + assert_not_empty contact.code + end + + def test_responces_error_with_email_error + name = 'new' + email = 'new@registrar@test' + phone = '+1.2' + + request_xml = <<-XML + + + + + + + #{name} + + #{phone} + #{email} + + + + + any + + + + + XML + + assert_no_difference 'Contact.count' do + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + end + + assert_epp_response :parameter_value_syntax_error + end + + def test_respects_custom_code + name = 'new' + code = 'custom-id' + session = epp_sessions(:api_bestnames) + + request_xml = <<-XML + + + + + + #{code} + + #{name} + + +1.2 + any@any.test + + + + + any + + + + + XML + + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => "session=#{session.session_id}" } + + contact = Contact.find_by(name: name) + assert_equal "#{session.user.registrar.code}:#{code}".upcase, contact.code + end + + def test_fails_when_required_attributes_are_missing + request_xml = <<-XML + + + + + + + \s +123.4 new@inbox.test @@ -24,17 +134,121 @@ class EppContactCreateBaseTest < ActionDispatch::IntegrationTest XML + assert_no_difference 'Contact.count' do + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + end + assert_epp_response :required_parameter_missing + end + + def test_does_not_save_address_when_address_processing_turned_off + name = 'new' + email = 'new@registrar.test' + phone = '+1.2' + + request_xml = <<-XML + + + + + + + #{name} + + 123 Example + Tallinn + FFF + 123456 + EE + + + #{phone} + #{email} + + + + + 123 + + + + + XML + assert_difference 'Contact.count' do - post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } end - response_xml = Nokogiri::XML(response.body) - assert_equal '1000', response_xml.at_css('result')[:code] - - contact = Contact.last + assert_epp_response :completed_without_address + contact = Contact.find_by(name: name) + assert_equal name, contact.name + assert_equal email, contact.email + assert_equal phone, contact.phone assert_not_empty contact.code - assert_equal 'New', contact.name - assert_equal 'new@inbox.test', contact.email - assert_equal '+123.4', contact.phone + assert_nil contact.city + assert_nil contact.street + assert_nil contact.zip + assert_nil contact.country_code + assert_nil contact.state end -end \ No newline at end of file + + def test_saves_address_when_address_processing_turned_on + Setting.address_processing = true + + name = 'new' + email = 'new@registrar.test' + phone = '+1.2' + street = '123 Example' + city = 'Tallinn' + state = 'Harjumaa' + zip = '123456' + country_code = 'EE' + + request_xml = <<-XML + + + + + + + #{name} + + #{street} + #{city} + #{state} + #{zip} + #{country_code} + + + #{phone} + #{email} + + + + + 123 + + + + + XML + + assert_difference 'Contact.count' do + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + end + + assert_epp_response :completed_successfully + contact = Contact.find_by(name: name) + assert_equal name, contact.name + assert_equal email, contact.email + assert_equal phone, contact.phone + assert_not_empty contact.code + assert_equal city, contact.city + assert_equal street, contact.street + assert_equal zip, contact.zip + assert_equal country_code, contact.country_code + assert_equal state, contact.state + end +end diff --git a/test/integration/epp/contact/delete/base_test.rb b/test/integration/epp/contact/delete/base_test.rb index 05e96d248..26ba63897 100644 --- a/test/integration/epp/contact/delete/base_test.rb +++ b/test/integration/epp/contact/delete/base_test.rb @@ -1,6 +1,6 @@ require 'test_helper' -class EppContactDeleteBaseTest < ActionDispatch::IntegrationTest +class EppContactDeleteBaseTest < EppTestCase def test_deletes_contact contact = deletable_contact @@ -21,11 +21,10 @@ class EppContactDeleteBaseTest < ActionDispatch::IntegrationTest XML assert_difference 'Contact.count', -1 do - post '/epp/command/delete', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_delete_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } end - response_xml = Nokogiri::XML(response.body) - assert_equal '1000', response_xml.at_css('result')[:code] - assert_equal 1, response_xml.css('result').size + assert_epp_response :completed_successfully end def test_undeletable_cannot_be_deleted @@ -49,16 +48,16 @@ class EppContactDeleteBaseTest < ActionDispatch::IntegrationTest XML assert_no_difference 'Contact.count' do - post '/epp/command/delete', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_delete_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } end - response_xml = Nokogiri::XML(response.body) - assert_equal '2305', response_xml.at_css('result')[:code] + assert_epp_response :object_association_prohibits_operation end private def deletable_contact - Domain.update_all(registrant_id: contacts(:william)) + Domain.update_all(registrant_id: contacts(:william).id) DomainContact.delete_all contacts(:john) end diff --git a/test/integration/epp/contact/info/base_test.rb b/test/integration/epp/contact/info/base_test.rb index 414c1a1d6..80dad97e8 100644 --- a/test/integration/epp/contact/info/base_test.rb +++ b/test/integration/epp/contact/info/base_test.rb @@ -1,6 +1,6 @@ require 'test_helper' -class EppContactInfoBaseTest < ActionDispatch::IntegrationTest +class EppContactInfoBaseTest < EppTestCase setup do @contact = contacts(:john) end @@ -29,11 +29,11 @@ class EppContactInfoBaseTest < ActionDispatch::IntegrationTest XML - post '/epp/command/info', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_info_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } response_xml = Nokogiri::XML(response.body) - assert_equal '1000', response_xml.at_css('result')[:code] - assert_equal 1, response_xml.css('result').size + assert_epp_response :completed_successfully assert_equal 'JOHN-001', response_xml.at_xpath('//contact:id', contact: xml_schema).text assert_equal 'ok', response_xml.at_xpath('//contact:status', contact: xml_schema)['s'] assert_equal 'john@inbox.test', response_xml.at_xpath('//contact:email', contact: xml_schema) @@ -44,8 +44,12 @@ class EppContactInfoBaseTest < ActionDispatch::IntegrationTest contact: xml_schema).text end - def test_contact_not_found - assert_nil Contact.find_by(code: 'non-existing') + def test_hides_password_when_current_registrar_is_not_sponsoring + non_sponsoring_registrar = registrars(:goodnames) + @contact.update!(registrar: non_sponsoring_registrar) + + # https://github.com/internetee/registry/issues/415 + @contact.update_columns(code: @contact.code.upcase) request_xml = <<-XML @@ -53,17 +57,19 @@ class EppContactInfoBaseTest < ActionDispatch::IntegrationTest - non-existing + #{@contact.code} XML - post '/epp/command/info', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_info_path, params: { frame: request_xml }, headers: { 'HTTP_COOKIE' => + 'session=api_bestnames' } + assert_epp_response :completed_successfully response_xml = Nokogiri::XML(response.body) - assert_equal '2303', response_xml.at_css('result')[:code] + assert_nil response_xml.at_xpath('//contact:authInfo', contact: xml_schema) end private @@ -71,4 +77,4 @@ class EppContactInfoBaseTest < ActionDispatch::IntegrationTest def xml_schema 'https://epp.tld.ee/schema/contact-ee-1.1.xsd' end -end \ No newline at end of file +end diff --git a/test/integration/epp/contact/transfer/base_test.rb b/test/integration/epp/contact/transfer/base_test.rb new file mode 100644 index 000000000..2d4ebb62c --- /dev/null +++ b/test/integration/epp/contact/transfer/base_test.rb @@ -0,0 +1,24 @@ +require 'test_helper' + +class EppContactTransferBaseTest < EppTestCase + # https://github.com/internetee/registry/issues/676 + def test_not_implemented + request_xml = <<-XML + + + + + + any + + + + + XML + + post epp_transfer_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + + assert_epp_response :unimplemented + end +end diff --git a/test/integration/epp/contact/update/base_test.rb b/test/integration/epp/contact/update/base_test.rb index 2c0486a07..98c0e4462 100644 --- a/test/integration/epp/contact/update/base_test.rb +++ b/test/integration/epp/contact/update/base_test.rb @@ -1,6 +1,6 @@ require 'test_helper' -class EppContactUpdateBaseTest < ActionDispatch::IntegrationTest +class EppContactUpdateBaseTest < EppTestCase include ActionMailer::TestHelper setup do @@ -37,12 +37,11 @@ class EppContactUpdateBaseTest < ActionDispatch::IntegrationTest XML - post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } @contact.reload - response_xml = Nokogiri::XML(response.body) - assert_equal '1000', response_xml.at_css('result')[:code] - assert_equal 1, response_xml.css('result').size + assert_epp_response :completed_successfully assert_equal 'new name', @contact.name assert_equal 'new-email@inbox.test', @contact.email assert_equal '+123.4', @contact.phone @@ -71,7 +70,8 @@ class EppContactUpdateBaseTest < ActionDispatch::IntegrationTest XML - post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } assert_emails 1 end @@ -99,7 +99,8 @@ class EppContactUpdateBaseTest < ActionDispatch::IntegrationTest XML - post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } assert_no_emails end @@ -130,7 +131,8 @@ class EppContactUpdateBaseTest < ActionDispatch::IntegrationTest XML - post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } assert_no_emails end @@ -156,10 +158,171 @@ class EppContactUpdateBaseTest < ActionDispatch::IntegrationTest XML - post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } - response_xml = Nokogiri::XML(response.body) - assert_equal '2303', response_xml.at_css('result')[:code] + assert_epp_response :object_does_not_exist + end + + def test_ident_code_cannot_be_updated + new_ident_code = '12345' + assert_not_equal new_ident_code, @contact.ident + + # https://github.com/internetee/registry/issues/415 + @contact.update_columns(code: @contact.code.upcase) + + request_xml = <<-XML + + + + + + #{@contact.code} + + + + + + + + + #{new_ident_code} + + + + + XML + assert_no_changes -> { @contact.updated_at } do + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + end + assert_epp_response :data_management_policy_violation + end + + # https://github.com/internetee/registry/issues/576 + def test_ident_type_and_ident_country_code_can_be_updated_when_absent + @contact.update_columns(ident: 'test', ident_type: nil, ident_country_code: nil) + + # https://github.com/internetee/registry/issues/415 + @contact.update_columns(code: @contact.code.upcase) + + request_xml = <<-XML + + + + + + #{@contact.code} + + + + + + + + #{@contact.ident} + + + + + XML + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + + assert_epp_response :completed_successfully + end + + def test_updates_address_when_address_processing_turned_on + @contact.update_columns(code: @contact.code.upcase) + Setting.address_processing = true + + street = '123 Example' + city = 'Tallinn' + state = 'Harjumaa' + zip = '123456' + country_code = 'EE' + + request_xml = <<-XML + + + + + + #{@contact.code} + + + + #{street} + #{city} + #{state} + #{zip} + #{country_code} + + + + + + + + XML + + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + + assert_epp_response :completed_successfully + @contact.reload + + assert_equal city, @contact.city + assert_equal street, @contact.street + assert_equal zip, @contact.zip + assert_equal country_code, @contact.country_code + assert_equal state, @contact.state + end + + def test_does_not_update_address_when_address_processing_turned_off + @contact.update_columns(code: @contact.code.upcase) + + street = '123 Example' + city = 'Tallinn' + state = 'Harjumaa' + zip = '123456' + country_code = 'EE' + + request_xml = <<-XML + + + + + + #{@contact.code} + + + + #{street} + #{city} + #{state} + #{zip} + #{country_code} + + + + + + + + XML + + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + + assert_epp_response :completed_without_address + @contact.reload + + assert_nil @contact.city + assert_nil @contact.street + assert_nil @contact.zip + assert_nil @contact.country_code + assert_nil @contact.state end private @@ -167,6 +330,6 @@ class EppContactUpdateBaseTest < ActionDispatch::IntegrationTest def make_contact_free_of_domains_where_it_acts_as_a_registrant(contact) other_contact = contacts(:william) assert_not_equal other_contact, contact - Domain.update_all(registrant_id: other_contact) + Domain.update_all(registrant_id: other_contact.id) end -end \ No newline at end of file +end diff --git a/test/integration/epp/domain/base_test.rb b/test/integration/epp/domain/base_test.rb new file mode 100644 index 000000000..34d9fb2bd --- /dev/null +++ b/test/integration/epp/domain/base_test.rb @@ -0,0 +1,22 @@ +require 'test_helper' + +class EppDomainBaseTest < EppTestCase + def test_non_existent_domain + request_xml = <<-XML + + + + + + non-existent.test + + + + + XML + post epp_info_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + + assert_epp_response :object_does_not_exist + end +end diff --git a/test/integration/epp/domain/check/auction_test.rb b/test/integration/epp/domain/check/auction_test.rb index 6a2722dc5..9fee851b6 100644 --- a/test/integration/epp/domain/check/auction_test.rb +++ b/test/integration/epp/domain/check/auction_test.rb @@ -1,7 +1,7 @@ # encoding: UTF-8 require 'test_helper' -class EppDomainCheckAuctionTest < ApplicationIntegrationTest +class EppDomainCheckAuctionTest < EppTestCase setup do @auction = auctions(:one) @idn_auction = auctions(:idn) @@ -28,11 +28,11 @@ class EppDomainCheckAuctionTest < ApplicationIntegrationTest XML - post '/epp/command/check', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_check_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } response_xml = Nokogiri::XML(response.body) - assert_equal '1000', response_xml.at_css('result')[:code] - assert_equal 1, response_xml.css('result').size + assert_epp_response :completed_successfully assert_equal '0', response_xml.at_xpath('//domain:name', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd')['avail'] assert_equal 'Domain is at auction', response_xml.at_xpath('//domain:reason', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text end @@ -53,11 +53,11 @@ class EppDomainCheckAuctionTest < ApplicationIntegrationTest XML - post '/epp/command/check', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_check_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } response_xml = Nokogiri::XML(response.body) - assert_equal '1000', response_xml.at_css('result')[:code] - assert_equal 1, response_xml.css('result').size + assert_epp_response :completed_successfully assert_equal '0', response_xml.at_xpath('//domain:name', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd')['avail'] assert_equal 'Domain is at auction', response_xml.at_xpath('//domain:reason', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text end @@ -78,11 +78,11 @@ class EppDomainCheckAuctionTest < ApplicationIntegrationTest XML - post '/epp/command/check', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_check_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } response_xml = Nokogiri::XML(response.body) - assert_equal '1000', response_xml.at_css('result')[:code] - assert_equal 1, response_xml.css('result').size + assert_epp_response :completed_successfully assert_equal '0', response_xml.at_xpath('//domain:name', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd')['avail'] assert_equal 'Domain is at auction', response_xml.at_xpath('//domain:reason', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text end @@ -103,11 +103,11 @@ class EppDomainCheckAuctionTest < ApplicationIntegrationTest XML - post '/epp/command/check', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_check_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } response_xml = Nokogiri::XML(response.body) - assert_equal '1000', response_xml.at_css('result')[:code] - assert_equal 1, response_xml.css('result').size + assert_epp_response :completed_successfully assert_equal '0', response_xml.at_xpath('//domain:name', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd')['avail'] assert_equal 'Awaiting payment', response_xml.at_xpath('//domain:reason', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text end @@ -128,11 +128,11 @@ class EppDomainCheckAuctionTest < ApplicationIntegrationTest XML - post '/epp/command/check', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_check_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } response_xml = Nokogiri::XML(response.body) - assert_equal '1000', response_xml.at_css('result')[:code] - assert_equal 1, response_xml.css('result').size + assert_epp_response :completed_successfully assert_equal '1', response_xml.at_xpath('//domain:name', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd')['avail'] assert_nil response_xml.at_xpath('//domain:reason', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd') end diff --git a/test/integration/epp/domain/check/base_test.rb b/test/integration/epp/domain/check/base_test.rb index 65e746947..5966f6239 100644 --- a/test/integration/epp/domain/check/base_test.rb +++ b/test/integration/epp/domain/check/base_test.rb @@ -1,6 +1,6 @@ require 'test_helper' -class EppDomainCheckBaseTest < ApplicationIntegrationTest +class EppDomainCheckBaseTest < EppTestCase def test_returns_valid_response request_xml = <<-XML @@ -15,11 +15,11 @@ class EppDomainCheckBaseTest < ApplicationIntegrationTest XML - post '/epp/command/check', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_check_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } response_xml = Nokogiri::XML(response.body) - assert_equal '1000', response_xml.at_css('result')[:code] - assert_equal 1, response_xml.css('result').size + assert_epp_response :completed_successfully assert_equal 'some.test', response_xml.at_xpath('//domain:name', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text end @@ -37,7 +37,8 @@ class EppDomainCheckBaseTest < ApplicationIntegrationTest XML - post '/epp/command/check', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_check_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } response_xml = Nokogiri::XML(response.body) assert_equal '1', response_xml.at_xpath('//domain:name', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd')['avail'] @@ -60,7 +61,8 @@ class EppDomainCheckBaseTest < ApplicationIntegrationTest XML - post '/epp/command/check', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_check_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } response_xml = Nokogiri::XML(response.body) assert_equal '1', response_xml.at_xpath('//domain:name', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd')['avail'] @@ -81,7 +83,8 @@ class EppDomainCheckBaseTest < ApplicationIntegrationTest XML - post '/epp/command/check', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_check_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } response_xml = Nokogiri::XML(response.body) assert_equal '0', response_xml.at_xpath('//domain:name', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd')['avail'] @@ -104,7 +107,8 @@ class EppDomainCheckBaseTest < ApplicationIntegrationTest XML - post '/epp/command/check', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_check_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } response_xml = Nokogiri::XML(response.body) assert_equal '0', response_xml.at_xpath('//domain:name', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd')['avail'] @@ -127,7 +131,8 @@ class EppDomainCheckBaseTest < ApplicationIntegrationTest XML - post '/epp/command/check', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_check_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } response_xml = Nokogiri::XML(response.body) assert_equal '0', response_xml.at_xpath('//domain:name', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd')['avail'] @@ -150,7 +155,8 @@ class EppDomainCheckBaseTest < ApplicationIntegrationTest XML - post '/epp/command/check', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_check_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } response_xml = Nokogiri::XML(response.body) assert_equal '0', response_xml.at_xpath('//domain:name', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd')['avail'] @@ -173,7 +179,8 @@ class EppDomainCheckBaseTest < ApplicationIntegrationTest XML - post '/epp/command/check', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_check_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } response_xml = Nokogiri::XML(response.body) assert_equal 3, response_xml.xpath('//domain:cd', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').size diff --git a/test/integration/epp/domain/create/auction_idn_test.rb b/test/integration/epp/domain/create/auction_idn_test.rb index 52bc49a98..822253ee5 100644 --- a/test/integration/epp/domain/create/auction_idn_test.rb +++ b/test/integration/epp/domain/create/auction_idn_test.rb @@ -1,7 +1,7 @@ # encoding: UTF-8 require 'test_helper' -class EppDomainCreateAuctionIdnTest < ApplicationIntegrationTest +class EppDomainCreateAuctionIdnTest < EppTestCase def setup super @@ -39,18 +39,15 @@ class EppDomainCreateAuctionIdnTest < ApplicationIntegrationTest XML assert_no_difference 'Domain.count' do - post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } end refute Domain.where(name: @idn_auction.domain).exists? @idn_auction.reload refute @idn_auction.domain_registered? - - response_xml = Nokogiri::XML(response.body) - assert_equal '2003', response_xml.at_css('result')[:code] - assert_equal 'Required parameter missing; reserved>pw element is required', - response_xml.at_css('result msg').text + assert_epp_response :required_parameter_missing end def test_domain_with_unicode_idn_cannot_be_registered_without_registration_code @@ -77,18 +74,15 @@ class EppDomainCreateAuctionIdnTest < ApplicationIntegrationTest XML assert_no_difference 'Domain.count' do - post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames'} end refute Domain.where(name: @idn_auction.domain).exists? @idn_auction.reload refute @idn_auction.domain_registered? - - response_xml = Nokogiri::XML(response.body) - assert_equal '2003', response_xml.at_css('result')[:code] - assert_equal 'Required parameter missing; reserved>pw element is required', - response_xml.at_css('result msg').text + assert_epp_response :required_parameter_missing end def test_domain_with_ascii_idn_cannot_be_registered_without_winning_the_auction @@ -114,18 +108,15 @@ class EppDomainCreateAuctionIdnTest < ApplicationIntegrationTest XML assert_no_difference 'Domain.count' do - post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames'} end refute Domain.where(name: @idn_auction.domain).exists? @idn_auction.reload refute @idn_auction.domain_registered? - - response_xml = Nokogiri::XML(response.body) - assert_equal '2306', response_xml.at_css('result')[:code] - assert_equal 'Parameter value policy error: domain is at auction', - response_xml.at_css('result msg').text + assert_epp_response :parameter_value_policy_error end def test_domain_with_unicode_idn_cannot_be_registered_without_winning_the_auction @@ -151,55 +142,15 @@ class EppDomainCreateAuctionIdnTest < ApplicationIntegrationTest XML assert_no_difference 'Domain.count' do - post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames'} end refute Domain.where(name: @idn_auction.domain).exists? @idn_auction.reload refute @idn_auction.domain_registered? - - response_xml = Nokogiri::XML(response.body) - assert_equal '2306', response_xml.at_css('result')[:code] - assert_equal 'Parameter value policy error: domain is at auction', - response_xml.at_css('result msg').text - end - - def test_domain_with_unicode_idn_cannot_be_registered_without_winning_the_auction - @idn_auction.started! - - request_xml = <<-XML - - - - - - püramiid.test - #{contacts(:john).code} - - - - - #{'test' * 2000} - - - - - XML - - assert_no_difference 'Domain.count' do - post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' - end - - refute Domain.where(name: @idn_auction.domain).exists? - - @idn_auction.reload - refute @idn_auction.domain_registered? - - response_xml = Nokogiri::XML(response.body) - assert_equal '2306', response_xml.at_css('result')[:code] - assert_equal 'Parameter value policy error: domain is at auction', - response_xml.at_css('result msg').text + assert_epp_response :parameter_value_policy_error end def test_registers_unicode_domain_with_correct_registration_code_when_payment_is_received @@ -229,16 +180,14 @@ class EppDomainCreateAuctionIdnTest < ApplicationIntegrationTest XML assert_difference 'Domain.count' do - post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames'} end @idn_auction.reload assert @idn_auction.domain_registered? assert Domain.where(name: @idn_auction.domain).exists? - - response_xml = Nokogiri::XML(response.body) - assert_equal '1000', response_xml.at_css('result')[:code] - assert_equal 1, Nokogiri::XML(response.body).css('result').size + assert_epp_response :completed_successfully end def test_registers_ascii_domain_with_correct_registration_code_when_payment_is_received @@ -268,15 +217,13 @@ class EppDomainCreateAuctionIdnTest < ApplicationIntegrationTest XML assert_difference 'Domain.count' do - post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames'} end @idn_auction.reload assert @idn_auction.domain_registered? assert Domain.where(name: @idn_auction.domain).exists? - - response_xml = Nokogiri::XML(response.body) - assert_equal '1000', response_xml.at_css('result')[:code] - assert_equal 1, Nokogiri::XML(response.body).css('result').size + assert_epp_response :completed_successfully end end diff --git a/test/integration/epp/domain/create/auction_test.rb b/test/integration/epp/domain/create/auction_test.rb index cb3a4f3c3..7e4c2ecb7 100644 --- a/test/integration/epp/domain/create/auction_test.rb +++ b/test/integration/epp/domain/create/auction_test.rb @@ -1,6 +1,6 @@ require 'test_helper' -class EppDomainCreateAuctionTest < ApplicationIntegrationTest +class EppDomainCreateAuctionTest < EppTestCase setup do @auction = auctions(:one) Domain.release_to_auction = true @@ -31,11 +31,10 @@ class EppDomainCreateAuctionTest < ApplicationIntegrationTest XML assert_difference 'Domain.count' do - post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } end - response_xml = Nokogiri::XML(response.body) - assert_equal '1000', response_xml.at_css('result')[:code] - assert_equal 1, Nokogiri::XML(response.body).css('result').size + assert_epp_response :completed_successfully end def test_registers_domain_with_correct_registration_code_after_another_auction_when_payment_is_received @@ -70,11 +69,10 @@ class EppDomainCreateAuctionTest < ApplicationIntegrationTest XML assert_difference 'Domain.count' do - post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } end - response_xml = Nokogiri::XML(response.body) - assert_equal '1000', response_xml.at_css('result')[:code] - assert_equal 1, Nokogiri::XML(response.body).css('result').size + assert_epp_response :completed_successfully end def test_registers_domain_with_correct_registration_code_when_payment_is_received @@ -104,15 +102,13 @@ class EppDomainCreateAuctionTest < ApplicationIntegrationTest XML assert_difference 'Domain.count' do - post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } end @auction.reload assert @auction.domain_registered? - - response_xml = Nokogiri::XML(response.body) - assert_equal '1000', response_xml.at_css('result')[:code] - assert_equal 1, Nokogiri::XML(response.body).css('result').size + assert_epp_response :completed_successfully end def test_domain_cannot_be_registered_without_registration_code @@ -139,12 +135,10 @@ class EppDomainCreateAuctionTest < ApplicationIntegrationTest XML assert_no_difference 'Domain.count' do - post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } end - response_xml = Nokogiri::XML(response.body) - assert_equal '2003', response_xml.at_css('result')[:code] - assert_equal 'Required parameter missing; reserved>pw element is required', - response_xml.at_css('result msg').text + assert_epp_response :required_parameter_missing end def test_domain_cannot_be_registered_with_wrong_registration_code @@ -174,12 +168,10 @@ class EppDomainCreateAuctionTest < ApplicationIntegrationTest XML assert_no_difference 'Domain.count' do - post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } end - response_xml = Nokogiri::XML(response.body) - assert_equal '2202', response_xml.at_css('result')[:code] - assert_equal 'Invalid authorization information; invalid reserved>pw value', - response_xml.at_css('result msg').text + assert_epp_response :invalid_authorization_information end def test_domain_cannot_be_registered_when_payment_is_not_received @@ -208,12 +200,10 @@ class EppDomainCreateAuctionTest < ApplicationIntegrationTest XML assert_no_difference 'Domain.count' do - post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } end - response_xml = Nokogiri::XML(response.body) - assert_equal '2003', response_xml.at_css('result')[:code] - assert_equal 'Required parameter missing; reserved>pw element required for reserved domains', - response_xml.at_css('result msg').text + assert_epp_response :required_parameter_missing end def test_domain_cannot_be_registered_when_at_auction @@ -238,11 +228,9 @@ class EppDomainCreateAuctionTest < ApplicationIntegrationTest XML assert_no_difference 'Domain.count' do - post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } end - response_xml = Nokogiri::XML(response.body) - assert_equal '2306', response_xml.at_css('result')[:code] - assert_equal 'Parameter value policy error: domain is at auction', - response_xml.at_css('result msg').text + assert_epp_response :parameter_value_policy_error end end diff --git a/test/integration/epp/domain/create/base_test.rb b/test/integration/epp/domain/create/base_test.rb index ff3a856df..9d817524d 100644 --- a/test/integration/epp/domain/create/base_test.rb +++ b/test/integration/epp/domain/create/base_test.rb @@ -1,15 +1,51 @@ require 'test_helper' -class EppDomainCreateBaseTest < ApplicationIntegrationTest - def test_domain_can_be_registered_with_required_attributes_only +class EppDomainCreateBaseTest < EppTestCase + + def test_not_registers_domain_without_legaldoc + now = Time.zone.parse('2010-07-05') + travel_to now + name = "new.#{dns_zones(:one).origin}" + contact = contacts(:john) + registrant = contact.becomes(Registrant) + request_xml = <<-XML - new.test - john-001 + #{name} + #{registrant.code} + + + + + XML + + assert_no_difference 'Domain.count' do + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + end + + assert_epp_response :required_parameter_missing + end + + def test_registers_new_domain_with_required_attributes + now = Time.zone.parse('2010-07-05') + travel_to now + name = "new.#{dns_zones(:one).origin}" + contact = contacts(:john) + registrant = contact.becomes(Registrant) + + request_xml = <<-XML + + + + + + #{name} + #{registrant.code} @@ -22,15 +58,343 @@ class EppDomainCreateBaseTest < ApplicationIntegrationTest XML assert_difference 'Domain.count' do - post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } end - domain = Domain.last - assert_equal 'new.test', domain.name - assert_equal contacts(:john).becomes(Registrant), domain.registrant + assert_epp_response :completed_successfully - response_xml = Nokogiri::XML(response.body) - assert_equal '1000', response_xml.at_css('result')[:code] - assert_equal 1, Nokogiri::XML(response.body).css('result').size + domain = Domain.find_by(name: name) + assert_equal name, domain.name + assert_equal registrant, domain.registrant + assert_equal [contact], domain.admin_contacts + assert_equal [contact], domain.tech_contacts + assert_not_empty domain.transfer_code + + default_registration_period = 1.year + 1.day + assert_equal now + default_registration_period, domain.expire_time + end + + def test_registers_domain_without_legaldoc_if_optout + now = Time.zone.parse('2010-07-05') + travel_to now + name = "new.#{dns_zones(:one).origin}" + contact = contacts(:john) + registrant = contact.becomes(Registrant) + registrar = registrant.registrar + + registrar.legaldoc_optout = true + registrar.save(validate: false) + + request_xml = <<-XML + + + + + + #{name} + #{registrant.code} + + + + + XML + + assert_difference 'Domain.count' do + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + end + + assert_epp_response :completed_successfully + + domain = Domain.find_by(name: name) + assert_equal name, domain.name + assert_equal registrant, domain.registrant + end + + def test_does_not_registers_domain_without_legaldoc_if_mandatory + now = Time.zone.parse('2010-07-05') + travel_to now + name = "new.#{dns_zones(:one).origin}" + contact = contacts(:john) + registrant = contact.becomes(Registrant) + registrar = registrant.registrar + + assert registrar.legaldoc_mandatory? + + request_xml = <<-XML + + + + + + #{name} + #{registrant.code} + + + + + XML + + + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + + assert_epp_response :required_parameter_missing + Setting.legal_document_is_mandatory = false + + assert_not registrar.legaldoc_mandatory? + assert_not Setting.legal_document_is_mandatory + + assert_difference 'Domain.count' do + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + end + end + + def test_registers_reserved_domain_with_registration_code + reserved_domain = reserved_domains(:one) + registration_code = reserved_domain.registration_code + + request_xml = <<-XML + + + + + + #{reserved_domain.name} + #{contacts(:john).code} + + + + + #{'test' * 2000} + + #{registration_code} + + + + + + XML + + assert_difference 'Domain.count' do + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + end + assert_epp_response :completed_successfully + + reserved_domain.reload + assert_not_equal registration_code, reserved_domain.registration_code + end + + def test_respects_custom_transfer_code + name = "new.#{dns_zones(:one).origin}" + transfer_code = 'custom-transfer-code' + + request_xml = <<-XML + + + + + + #{name} + #{contacts(:john).code} + + #{transfer_code} + + + + + + #{'test' * 2000} + + + + + XML + + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + + assert_epp_response :completed_successfully + assert_equal transfer_code, Domain.find_by(name: name).transfer_code + end + + def test_blocked_domain_cannot_be_registered + blocked_domain = 'blocked.test' + assert BlockedDomain.find_by(name: blocked_domain) + + request_xml = <<-XML + + + + + + #{blocked_domain} + #{contacts(:john).code} + + + + + #{'test' * 2000} + + + + + XML + + assert_no_difference 'Domain.count' do + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + end + assert_epp_response :data_management_policy_violation + end + + def test_blocked_punicode_domain_cannot_be_registered + blocked_domain = 'blockedäöüõ.test' + assert BlockedDomain.find_by(name: blocked_domain) + + request_xml = <<-XML + + + + + + #{SimpleIDN.to_ascii('blockedäöüõ.test')} + #{contacts(:john).code} + + + + + #{'test' * 2000} + + + + + XML + + assert_no_difference 'Domain.count' do + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + end + assert_epp_response :data_management_policy_violation + end + + def test_reserved_domain_cannot_be_registered_with_wrong_registration_code + request_xml = <<-XML + + + + + + #{reserved_domains(:one).name} + #{contacts(:john).code} + + + + + #{'test' * 2000} + + wrong + + + + + + XML + + assert_no_difference 'Domain.count' do + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + end + assert_epp_response :invalid_authorization_information + end + + def test_reserved_domain_cannot_be_registered_without_registration_code + reserved_domain = reserved_domains(:one) + + request_xml = <<-XML + + + + + + #{reserved_domain.name} + #{contacts(:john).code} + + + + + #{'test' * 2000} + + + + + XML + + assert_no_difference 'Domain.count' do + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + end + assert_epp_response :required_parameter_missing + end + + def test_insufficient_funds + session = epp_sessions(:api_bestnames) + session.user.registrar.accounts.first.update!(balance: 0) + + request_xml = <<-XML + + + + + + new.test + #{contacts(:john).code} + + + + + #{'test' * 2000} + + + + + XML + assert_no_difference 'Domain.count' do + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => "session=#{session.session_id}" } + end + assert_epp_response :billing_failure + end + + def test_no_price + assert_nil Billing::Price.find_by(duration: '2 months') + + request_xml = <<-XML + + + + + + new.test + 2 + john-001 + + + + + #{'test' * 2000} + + + + + XML + assert_no_difference 'Domain.count' do + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + end + assert_epp_response :billing_failure end end diff --git a/test/integration/epp/domain/create/nameservers_test.rb b/test/integration/epp/domain/create/nameservers_test.rb deleted file mode 100644 index 954d1f300..000000000 --- a/test/integration/epp/domain/create/nameservers_test.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'test_helper' - -class EppDomainCreateNameserversTest < ApplicationIntegrationTest - # Glue record requirement - def test_nameserver_ip_address_is_required_if_hostname_is_under_the_same_domain - request_xml = <<-XML - - - - - - new.test - - - ns1.new.test - - - john-001 - - - - - test - - - - - XML - - assert_no_difference 'Domain.count' do - post '/epp/command/create', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_bestnames' } - end - assert_equal '2003', Nokogiri::XML(response.body).at_css('result')[:code] - end -end diff --git a/test/integration/epp/domain/create/reserved_test.rb b/test/integration/epp/domain/create/reserved_test.rb deleted file mode 100644 index 1a57cd220..000000000 --- a/test/integration/epp/domain/create/reserved_test.rb +++ /dev/null @@ -1,142 +0,0 @@ -require 'test_helper' - -class EppDomainCreateReservedTest < ApplicationIntegrationTest - setup do - @reserved_domain = reserved_domains(:one) - end - - def test_registers_reserved_domain_with_correct_registration_code - assert_equal 'reserved.test', @reserved_domain.name - assert_equal 'reserved-001', @reserved_domain.registration_code - - request_xml = <<-XML - - - - - - reserved.test - john-001 - - - - - #{'test' * 2000} - - reserved-001 - - - - - - XML - - assert_difference 'Domain.count' do - post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' - end - - response_xml = Nokogiri::XML(response.body) - assert_equal '1000', response_xml.at_css('result')[:code] - assert_equal 1, Nokogiri::XML(response.body).css('result').size - end - - def test_registering_reserved_domain_regenerates_registration_code - assert_equal 'reserved.test', @reserved_domain.name - assert_equal 'reserved-001', @reserved_domain.registration_code - - request_xml = <<-XML - - - - - - reserved.test - john-001 - - - - - #{'test' * 2000} - - reserved-001 - - - - - - XML - - post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' - @reserved_domain.reload - - assert_not_equal 'reserved-001', @reserved_domain.registration_code - end - - def test_domain_cannot_be_registered_with_wrong_registration_code - assert_equal 'reserved.test', @reserved_domain.name - assert_equal 'reserved-001', @reserved_domain.registration_code - - request_xml = <<-XML - - - - - - reserved.test - john-001 - - - - - #{'test' * 2000} - - wrong - - - - - - XML - - assert_no_difference 'Domain.count' do - post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' - end - - response_xml = Nokogiri::XML(response.body) - assert_equal '2202', response_xml.at_css('result')[:code] - assert_equal 'Invalid authorization information; invalid reserved>pw value', - response_xml.at_css('result msg').text - end - - def test_domain_cannot_be_registered_without_registration_code - assert_equal 'reserved.test', @reserved_domain.name - - request_xml = <<-XML - - - - - - reserved.test - john-001 - - - - - #{'test' * 2000} - - - - - XML - - assert_no_difference 'Domain.count' do - post '/epp/command/create', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' - end - - response_xml = Nokogiri::XML(response.body) - assert_equal '2003', response_xml.at_css('result')[:code] - assert_equal 'Required parameter missing; reserved>pw element required for reserved domains', - response_xml.at_css('result msg').text - end -end diff --git a/test/integration/epp/domain/create/transfer_code_test.rb b/test/integration/epp/domain/create/transfer_code_test.rb deleted file mode 100644 index 131baf67a..000000000 --- a/test/integration/epp/domain/create/transfer_code_test.rb +++ /dev/null @@ -1,64 +0,0 @@ -require 'test_helper' - -class EppDomainCreateTransferCodeTest < ApplicationIntegrationTest - setup do - travel_to Time.zone.parse('2010-07-05') - end - - def test_generates_default - request_xml = <<-XML - - - - - - brandnew.test - 1 - john-001 - - - - - #{'test' * 2000} - - - - - XML - - post '/epp/command/create', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_bestnames' } - refute_empty Domain.find_by(name: 'brandnew.test').transfer_code - assert_equal '1000', Nokogiri::XML(response.body).at_css('result')[:code] - assert_equal 1, Nokogiri::XML(response.body).css('result').size - end - - def test_honors_custom - request_xml = <<-XML - - - - - - brandnew.test - 1 - john-001 - - 1058ad73 - - - - - - #{'test' * 2000} - - - - - XML - - post '/epp/command/create', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_bestnames' } - assert_equal '1058ad73', Domain.find_by(name: 'brandnew.test').transfer_code - assert_equal '1000', Nokogiri::XML(response.body).at_css('result')[:code] - assert_equal 1, Nokogiri::XML(response.body).css('result').size - end -end diff --git a/test/integration/epp/domain/delete/base_test.rb b/test/integration/epp/domain/delete/base_test.rb index 0a2a4308a..c7147957c 100644 --- a/test/integration/epp/domain/delete/base_test.rb +++ b/test/integration/epp/domain/delete/base_test.rb @@ -1,16 +1,16 @@ require 'test_helper' -class EppDomainDeleteBaseTest < ActionDispatch::IntegrationTest +class EppDomainDeleteBaseTest < EppTestCase include ActionMailer::TestHelper setup do @domain = domains(:shop) - @original_confirmation_setting = Setting.request_confirmation_on_domain_deletion_enabled + @original_domain_delete_confirmation = Setting.request_confirmation_on_domain_deletion_enabled ActionMailer::Base.deliveries.clear end teardown do - Setting.request_confirmation_on_domain_deletion_enabled = @original_confirmation_setting + Setting.request_confirmation_on_domain_deletion_enabled = @original_domain_delete_confirmation end def test_bypasses_domain_and_registrant_and_contacts_validation @@ -34,10 +34,9 @@ class EppDomainDeleteBaseTest < ActionDispatch::IntegrationTest XML - post '/epp/command/delete', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_delete_path, params: { frame: request_xml }, headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } assert_includes Domain.find_by(name: 'invalid.test').statuses, DomainStatus::PENDING_DELETE_CONFIRMATION - assert_equal '1001', Nokogiri::XML(response.body).at_css('result')[:code] - assert_equal 1, Nokogiri::XML(response.body).css('result').size + assert_epp_response :completed_successfully_action_pending end def test_discarded_domain_cannot_be_deleted @@ -63,9 +62,9 @@ class EppDomainDeleteBaseTest < ActionDispatch::IntegrationTest XML assert_no_difference 'Domain.count' do - post '/epp/command/delete', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_delete_path, params: { frame: request_xml }, headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } end - assert_equal '2105', Nokogiri::XML(response.body).at_css('result')[:code] + assert_epp_response :object_status_prohibits_operation end def test_requests_registrant_confirmation_when_required @@ -90,14 +89,13 @@ class EppDomainDeleteBaseTest < ActionDispatch::IntegrationTest XML - post '/epp/command/delete', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_delete_path, params: { frame: request_xml }, headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } @domain.reload assert @domain.registrant_verification_asked? assert @domain.pending_delete_confirmation? assert_emails 1 - response_xml = Nokogiri::XML(response.body) - assert_equal '1001', response_xml.at_css('result')[:code] + assert_epp_response :completed_successfully_action_pending end def test_skips_registrant_confirmation_when_not_required @@ -122,14 +120,13 @@ class EppDomainDeleteBaseTest < ActionDispatch::IntegrationTest XML - post '/epp/command/delete', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_delete_path, params: { frame: request_xml }, headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } @domain.reload assert_not @domain.registrant_verification_asked? assert_not @domain.pending_delete_confirmation? assert_no_emails - response_xml = Nokogiri::XML(response.body) - assert_equal '1000', response_xml.at_css('result')[:code] + assert_epp_response :completed_successfully end def test_skips_registrant_confirmation_when_required_but_already_verified_by_registrar @@ -154,18 +151,18 @@ class EppDomainDeleteBaseTest < ActionDispatch::IntegrationTest XML - post '/epp/command/delete', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_delete_path, params: { frame: request_xml }, headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } @domain.reload assert_not @domain.registrant_verification_asked? assert_not @domain.pending_delete_confirmation? assert_no_emails - response_xml = Nokogiri::XML(response.body) - assert_equal '1000', response_xml.at_css('result')[:code] + assert_epp_response :completed_successfully end - def test_legal_document_is_required + def test_legal_document_is_optional assert_equal 'shop.test', @domain.name + Setting.request_confirmation_on_domain_deletion_enabled = false request_xml = <<-XML @@ -180,12 +177,9 @@ class EppDomainDeleteBaseTest < ActionDispatch::IntegrationTest XML - post '/epp/command/delete', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_delete_path, params: { frame: request_xml }, headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } - response_xml = Nokogiri::XML(response.body) - assert_equal '2003', response_xml.at_css('result')[:code] - assert_equal 'Required parameter missing: extension > extdata > legalDocument [legal_document]', - response_xml.at_css('result msg').text + assert_epp_response :completed_successfully end def test_domain_cannot_be_deleted_when_explicitly_prohibited_by_registrar @@ -210,38 +204,8 @@ class EppDomainDeleteBaseTest < ActionDispatch::IntegrationTest XML - post '/epp/command/delete', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_delete_path, params: { frame: request_xml }, headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } - response_xml = Nokogiri::XML(response.body) - assert_equal '2304', response_xml.at_css('result')[:code] - assert_equal 'Domain status prohibits operation', response_xml.at_css('result msg').text + assert_epp_response :object_status_prohibits_operation end - - def test_domain_not_found - assert_nil Domain.find_by(name: 'non-existing.test') - - request_xml = <<-XML - - - - - - non-existing.test - - - - - dGVzdCBmYWlsCg== - - - - - XML - - post '/epp/command/delete', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' - - response_xml = Nokogiri::XML(response.body) - assert_equal '2303', response_xml.at_css('result')[:code] - assert_equal 'Domain not found', response_xml.at_css('result msg').text - end -end \ No newline at end of file +end diff --git a/test/integration/epp/domain/domain_renew_test.rb b/test/integration/epp/domain/domain_renew_test.rb deleted file mode 100644 index ac48269ad..000000000 --- a/test/integration/epp/domain/domain_renew_test.rb +++ /dev/null @@ -1,32 +0,0 @@ -require 'test_helper' - -class EppDomainRenewTest < ApplicationIntegrationTest - self.use_transactional_fixtures = false - - setup do - travel_to Time.zone.parse('2010-07-05') - end - - def test_domain_cannot_be_renewed_when_invalid - request_xml = <<-XML - - - - - - invalid.test - 2010-07-05 - 1 - - - - - XML - - assert_no_changes -> { domains(:invalid).valid_to } do - post '/epp/command/renew', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' - end - assert_equal '2304', Nokogiri::XML(response.body).at_css('result')[:code], - Nokogiri::XML(response.body).css('result').text - end -end diff --git a/test/integration/epp/domain/domain_update_test.rb b/test/integration/epp/domain/domain_update_test.rb deleted file mode 100644 index bdd39a0a4..000000000 --- a/test/integration/epp/domain/domain_update_test.rb +++ /dev/null @@ -1,54 +0,0 @@ -require 'test_helper' - -class EppDomainUpdateTest < ApplicationIntegrationTest - def setup - @domain = domains(:shop) - end - - def test_update_domain - request_xml = <<-XML - - - - - - shop.test - - - f0ff7d17b0 - - - - - - - XML - - post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' - @domain.reload - assert_equal 'f0ff7d17b0', @domain.transfer_code - assert_equal '1000', Nokogiri::XML(response.body).at_css('result')[:code] - assert_equal 1, Nokogiri::XML(response.body).css('result').size - end - - def test_discarded_domain_cannot_be_updated - @domain.update!(statuses: [DomainStatus::DELETE_CANDIDATE]) - - request_xml = <<-XML - - - - - - shop.test - - - - - XML - - post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' - assert_equal '2105', Nokogiri::XML(response.body).at_css('result')[:code] - travel_back - end -end diff --git a/test/integration/epp/domain/info/base_test.rb b/test/integration/epp/domain/info/base_test.rb index 2ba273951..26f0ecce1 100644 --- a/test/integration/epp/domain/info/base_test.rb +++ b/test/integration/epp/domain/info/base_test.rb @@ -1,6 +1,6 @@ require 'test_helper' -class EppDomainInfoBaseTest < ApplicationIntegrationTest +class EppDomainInfoBaseTest < EppTestCase def test_returns_valid_response assert_equal 'john-001', contacts(:john).code domains(:shop).update_columns(statuses: [DomainStatus::OK], @@ -21,11 +21,11 @@ class EppDomainInfoBaseTest < ApplicationIntegrationTest XML - post '/epp/command/info', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_info_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } response_xml = Nokogiri::XML(response.body) - assert_equal '1000', response_xml.at_css('result')[:code] - assert_equal 1, response_xml.css('result').size + assert_epp_response :completed_successfully assert_equal 'shop.test', response_xml.at_xpath('//domain:name', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text assert_equal 'ok', response_xml.at_xpath('//domain:status', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd')['s'] assert_equal 'john-001', response_xml.at_xpath('//domain:registrant', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text @@ -50,7 +50,8 @@ class EppDomainInfoBaseTest < ApplicationIntegrationTest XML - post '/epp/command/info', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_info_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } response_xml = Nokogiri::XML(response.body) assert_equal '65078d5', response_xml.at_xpath('//domain:authInfo/domain:pw', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text @@ -77,7 +78,8 @@ class EppDomainInfoBaseTest < ApplicationIntegrationTest XML - post '/epp/command/info', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_goodnames' + post epp_info_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_goodnames' } response_xml = Nokogiri::XML(response.body) assert_equal '65078d5', response_xml.at_xpath('//domain:authInfo/domain:pw', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text @@ -100,33 +102,11 @@ class EppDomainInfoBaseTest < ApplicationIntegrationTest XML - post '/epp/command/info', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_goodnames' + post epp_info_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_goodnames' } response_xml = Nokogiri::XML(response.body) assert_nil response_xml.at_xpath('//domain:authInfo/domain:pw', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd') end - - def test_returns_not_found_error_when_domain_is_not_registered - assert DNS::DomainName.new('not-registered.test').not_registered? - - request_xml = <<-XML - - - - - - not-registered.test - - - - - XML - - post '/epp/command/info', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' - - response_xml = Nokogiri::XML(response.body) - assert_equal '2303', response_xml.at_css('result')[:code] - assert_equal 'Domain not found', response_xml.at_css('result msg').text - end end \ No newline at end of file diff --git a/test/integration/epp/domain/renew/base_test.rb b/test/integration/epp/domain/renew/base_test.rb new file mode 100644 index 000000000..541aab2a8 --- /dev/null +++ b/test/integration/epp/domain/renew/base_test.rb @@ -0,0 +1,170 @@ +require 'test_helper' + +class EppDomainRenewBaseTest < EppTestCase + self.use_transactional_tests = false + + def test_renews_domain + travel_to Time.zone.parse('2010-07-05') + domain = domains(:shop) + original_valid_to = domain.valid_to + default_renewal_period = 1.year + + request_xml = <<-XML + + + + + + #{domain.name} + #{domain.expire_time.to_date} + 1 + + + + + XML + + post epp_renew_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + domain.reload + + assert_epp_response :completed_successfully + assert_equal original_valid_to + default_renewal_period, domain.valid_to + end + + def test_domain_cannot_be_renewed_when_invalid + domain = domains(:invalid) + + request_xml = <<-XML + + + + + + #{domain.name} + #{domain.valid_to.to_date} + 1 + + + + + XML + + assert_no_changes -> { domain.valid_to } do + post epp_renew_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + domain.reload + end + assert_epp_response :object_status_prohibits_operation + end + + def test_domain_cannot_be_renewed_when_belongs_to_another_registrar + domain = domains(:metro) + session = epp_sessions(:api_bestnames) + assert_not_equal session.user.registrar, domain.registrar + + request_xml = <<-XML + + + + + + #{domain.name} + #{domain.valid_to.to_date} + 1 + + + + + XML + + assert_no_changes -> { domain.valid_to } do + post epp_renew_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => "session=#{session.session_id}" } + domain.reload + end + assert_epp_response :authorization_error + end + + def test_insufficient_funds + domain = domains(:shop) + session = epp_sessions(:api_bestnames) + session.user.registrar.accounts.first.update!(balance: 0) + + request_xml = <<-XML + + + + + + #{domain.name} + #{domain.expire_time.to_date} + 1 + + + + + XML + + assert_no_difference -> { domain.valid_to } do + post epp_renew_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => "session=#{session.session_id}" } + domain.reload + end + assert_epp_response :billing_failure + end + + def test_no_price + domain = domains(:shop) + assert_nil Billing::Price.find_by(duration: '2 months') + + request_xml = <<-XML + + + + + + #{domain.name} + #{domain.expire_time.to_date} + 2 + + + + + XML + + assert_no_changes -> { domain.valid_to } do + post epp_renew_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + domain.reload + end + assert_epp_response :billing_failure + end + + def test_fails_when_provided_expiration_date_is_wrong + domain = domains(:shop) + provided_expiration_date = Date.parse('2010-07-06') + assert_not_equal provided_expiration_date, domain.valid_to + + request_xml = <<-XML + + + + + + #{domain.name} + #{provided_expiration_date} + + + + + XML + + assert_no_changes -> { domain.valid_to } do + post epp_renew_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + domain.reload + end + assert_epp_response :parameter_value_policy_error + end +end diff --git a/test/integration/epp/domain/transfer/base_test.rb b/test/integration/epp/domain/transfer/base_test.rb deleted file mode 100644 index e220f8ebd..000000000 --- a/test/integration/epp/domain/transfer/base_test.rb +++ /dev/null @@ -1,24 +0,0 @@ -require 'test_helper' - -class EppDomainTransferBaseTest < ApplicationIntegrationTest - def test_non_existent_domain - request_xml = <<-XML - - - - - - non-existent.test - - any - - - - - - XML - - post '/epp/command/transfer', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_goodnames' } - assert_equal '2303', Nokogiri::XML(response.body).at_css('result')[:code] - end -end diff --git a/test/integration/epp/domain/transfer/query_test.rb b/test/integration/epp/domain/transfer/query_test.rb index 8a9c589c8..d6f62e223 100644 --- a/test/integration/epp/domain/transfer/query_test.rb +++ b/test/integration/epp/domain/transfer/query_test.rb @@ -1,11 +1,11 @@ require 'test_helper' -class EppDomainTransferQueryTest < ApplicationIntegrationTest +class EppDomainTransferQueryTest < EppTestCase def test_returns_domain_transfer_details - post '/epp/command/transfer', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_bestnames' } + post epp_transfer_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } xml_doc = Nokogiri::XML(response.body) - assert_equal '1000', xml_doc.at_css('result')[:code] - assert_equal 1, xml_doc.css('result').size + assert_epp_response :completed_successfully assert_equal 'shop.test', xml_doc.xpath('//domain:name', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text assert_equal 'serverApproved', xml_doc.xpath('//domain:trStatus', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text assert_equal 'goodnames', xml_doc.xpath('//domain:reID', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text @@ -29,14 +29,17 @@ class EppDomainTransferQueryTest < ApplicationIntegrationTest XML - post '/epp/command/transfer', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_bestnames' } - assert_equal '2201', Nokogiri::XML(response.body).at_css('result')[:code] + post epp_transfer_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + + assert_epp_response :invalid_authorization_information end def test_no_domain_transfer domains(:shop).transfers.delete_all - post '/epp/command/transfer', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_bestnames' } - assert_equal '2303', Nokogiri::XML(response.body).at_css('result')[:code] + post epp_transfer_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + assert_epp_response :object_does_not_exist end private diff --git a/test/integration/epp/domain/transfer/request_test.rb b/test/integration/epp/domain/transfer/request_test.rb index 82f453277..c7a838ca6 100644 --- a/test/integration/epp/domain/transfer/request_test.rb +++ b/test/integration/epp/domain/transfer/request_test.rb @@ -1,6 +1,6 @@ require 'test_helper' -class EppDomainTransferRequestTest < ApplicationIntegrationTest +class EppDomainTransferRequestTest < EppTestCase def setup @domain = domains(:shop) @new_registrar = registrars(:goodnames) @@ -13,25 +13,28 @@ class EppDomainTransferRequestTest < ApplicationIntegrationTest end def test_transfers_domain_at_once - post '/epp/command/transfer', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_goodnames' } - assert_equal '1000', Nokogiri::XML(response.body).at_css('result')[:code] - assert_equal 1, Nokogiri::XML(response.body).css('result').size + post epp_transfer_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_goodnames' } + assert_epp_response :completed_successfully end def test_creates_new_domain_transfer assert_difference -> { @domain.transfers.size } do - post '/epp/command/transfer', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_goodnames' } + post epp_transfer_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_goodnames' } end end def test_approves_automatically_if_auto_approval_is_enabled - post '/epp/command/transfer', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_goodnames' } + post epp_transfer_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_goodnames' } assert_equal 'serverApproved', Nokogiri::XML(response.body).xpath('//domain:trStatus', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text end def test_assigns_new_registrar - post '/epp/command/transfer', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_goodnames' } + post epp_transfer_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_goodnames' } @domain.reload assert_equal @new_registrar, @domain.registrar end @@ -39,7 +42,8 @@ class EppDomainTransferRequestTest < ApplicationIntegrationTest def test_regenerates_transfer_code @old_transfer_code = @domain.transfer_code - post '/epp/command/transfer', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_goodnames' } + post epp_transfer_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_goodnames' } @domain.reload refute_equal @domain.transfer_code, @old_transfer_code @@ -49,54 +53,59 @@ class EppDomainTransferRequestTest < ApplicationIntegrationTest @old_registrar = @domain.registrar assert_difference -> { @old_registrar.notifications.count } do - post '/epp/command/transfer', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_goodnames' } + post epp_transfer_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_goodnames' } end end def test_duplicates_registrant_admin_and_tech_contacts assert_difference -> { @new_registrar.contacts.size }, 3 do - post '/epp/command/transfer', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_goodnames' } + post epp_transfer_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_goodnames' } end end def test_reuses_identical_contact - post '/epp/command/transfer', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_goodnames' } + post epp_transfer_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_goodnames' } assert_equal 1, @new_registrar.contacts.where(name: 'William').size end def test_saves_legal_document - assert_difference -> { @domain.legal_documents(true).size } do - post '/epp/command/transfer', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_goodnames' } + assert_difference -> { @domain.legal_documents.reload.size } do + post epp_transfer_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_goodnames' } end end def test_non_transferable_domain @domain.update!(statuses: [DomainStatus::SERVER_TRANSFER_PROHIBITED]) - post '/epp/command/transfer', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_goodnames' } + post epp_transfer_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_goodnames' } domains(:shop).reload assert_equal registrars(:bestnames), domains(:shop).registrar - assert_equal '2304', Nokogiri::XML(response.body).at_css('result')[:code] + assert_epp_response :object_status_prohibits_operation end def test_discarded_domain_cannot_be_transferred @domain.update!(statuses: [DomainStatus::DELETE_CANDIDATE]) - post '/epp/command/transfer', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_goodnames' } + post epp_transfer_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_goodnames' } @domain.reload assert_equal registrars(:bestnames), @domain.registrar - assert_equal '2105', Nokogiri::XML(response.body).at_css('result')[:code] - travel_back + assert_epp_response :object_is_not_eligible_for_transfer end def test_same_registrar assert_no_difference -> { @domain.transfers.size } do - post '/epp/command/transfer', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_bestnames' } + post epp_transfer_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } end - - assert_equal '2002', Nokogiri::XML(response.body).at_css('result')[:code] + assert_epp_response :use_error end def test_wrong_transfer_code @@ -116,10 +125,12 @@ class EppDomainTransferRequestTest < ApplicationIntegrationTest XML - post '/epp/command/transfer', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_goodnames' } + post epp_transfer_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_goodnames' } @domain.reload + + assert_epp_response :invalid_authorization_information refute_equal @new_registrar, @domain.registrar - assert_equal '2201', Nokogiri::XML(response.body).at_css('result')[:code] end private diff --git a/test/integration/epp/domain/update/base_test.rb b/test/integration/epp/domain/update/base_test.rb new file mode 100644 index 000000000..de1ba84d8 --- /dev/null +++ b/test/integration/epp/domain/update/base_test.rb @@ -0,0 +1,511 @@ +require 'test_helper' + +class EppDomainUpdateBaseTest < EppTestCase + include ActionMailer::TestHelper + + setup do + @domain = domains(:shop) + @original_registrant_change_verification = + Setting.request_confrimation_on_registrant_change_enabled + ActionMailer::Base.deliveries.clear + end + + teardown do + Setting.request_confrimation_on_registrant_change_enabled = + @original_registrant_change_verification + end + + def test_update_domain + request_xml = <<-XML + + + + + + shop.test + + + f0ff7d17b0 + + + + + + + XML + + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + @domain.reload + assert_equal 'f0ff7d17b0', @domain.transfer_code + assert_epp_response :completed_successfully + end + + def test_discarded_domain_cannot_be_updated + @domain.update!(statuses: [DomainStatus::DELETE_CANDIDATE]) + + request_xml = <<-XML + + + + + + shop.test + + + + + XML + + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + assert_epp_response :object_status_prohibits_operation + end + + def test_does_not_return_server_delete_prohibited_status_when_pending_update_status_is_set + @domain.update!(statuses: [DomainStatus::SERVER_DELETE_PROHIBITED, + DomainStatus::PENDING_UPDATE]) + request_xml = <<-XML + + + + + + #{@domain.name} + + + + + XML + + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + + assert_epp_response :object_status_prohibits_operation + response_xml = Nokogiri::XML(response.body) + assert_equal DomainStatus::PENDING_UPDATE, response_xml.at_xpath('//domain:status', 'domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd').text + end + + def test_requires_verification_from_current_registrant_when_provided_registrant_is_a_new_one + Setting.request_confrimation_on_registrant_change_enabled = true + new_registrant = contacts(:william).becomes(Registrant) + assert_not_equal new_registrant, @domain.registrant + + request_xml = <<-XML + + + + + + #{@domain.name} + + #{new_registrant.code} + + + + + + #{'test' * 2000} + + + + + XML + + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + @domain.reload + + assert_epp_response :completed_successfully_action_pending + assert_not_equal new_registrant, @domain.registrant + assert @domain.registrant_verification_asked? + assert_includes @domain.statuses, DomainStatus::PENDING_UPDATE + assert_verification_and_notification_emails + end + + def test_requires_verification_from_current_registrant_when_not_yet_verified_by_registrar + Setting.request_confrimation_on_registrant_change_enabled = true + new_registrant = contacts(:william) + assert_not_equal new_registrant, @domain.registrant + + request_xml = <<-XML + + + + + + #{@domain.name} + + #{new_registrant.code} + + + + + + #{'test' * 2000} + + + + + XML + + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + @domain.reload + + assert_epp_response :completed_successfully_action_pending + assert_not_equal new_registrant, @domain.registrant + assert @domain.registrant_verification_asked? + assert_includes @domain.statuses, DomainStatus::PENDING_UPDATE + assert_verification_and_notification_emails + end + + def test_updates_registrant_when_legaldoc_is_not_mandatory + Setting.request_confrimation_on_registrant_change_enabled = true + new_registrant = contacts(:william) + assert_not_equal new_registrant, @domain.registrant + + @domain.registrar.legaldoc_optout = true + @domain.registrar.save(validate: false) + @domain.registrar.reload + + request_xml = <<-XML + + + + + + #{@domain.name} + + #{new_registrant.code} + + + + + + XML + + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + @domain.reload + + assert_epp_response :completed_successfully_action_pending + assert_not_equal new_registrant, @domain.registrant + assert @domain.registrant_verification_asked? + assert_includes @domain.statuses, DomainStatus::PENDING_UPDATE + assert_verification_and_notification_emails + end + + def test_dows_not_update_registrant_when_legaldoc_is_mandatory + Setting.request_confrimation_on_registrant_change_enabled = true + old_value = Setting.legal_document_is_mandatory + Setting.legal_document_is_mandatory = true + new_registrant = contacts(:william) + assert_not_equal new_registrant, @domain.registrant + + request_xml = <<-XML + + + + + + #{@domain.name} + + #{new_registrant.code} + + + + + + XML + + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + assert_epp_response :required_parameter_missing + Setting.legal_document_is_mandatory = old_value + end + + def test_skips_verification_when_provided_registrant_is_the_same_as_current_one + Setting.request_confrimation_on_registrant_change_enabled = true + + request_xml = <<-XML + + + + + + #{@domain.name} + + #{@domain.registrant.code} + + + + + + #{'test' * 2000} + + + + + XML + + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + @domain.reload + + assert_epp_response :completed_successfully + assert_not @domain.registrant_verification_asked? + refute_includes @domain.statuses, DomainStatus::PENDING_UPDATE + assert_no_emails + end + + def test_skips_verification_when_registrant_changed_with_dispute_password + Setting.request_confrimation_on_registrant_change_enabled = true + dispute = disputes(:expired) + dispute.update!(starts_at: Time.zone.now, expires_at: Time.zone.now + 5.days, closed: nil) + new_registrant = contacts(:william) + + assert @domain.disputed? + + request_xml = <<-XML + + + + + + #{@domain.name} + + #{new_registrant.code} + + + + + + #{'test' * 2000} + + #{dispute.password} + + + + + + XML + + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + @domain.reload + + assert_epp_response :completed_successfully + assert new_registrant, @domain.registrant + assert_not @domain.registrant_verification_asked? + assert_not @domain.disputed? + assert_no_emails + end + + def test_skips_verification_when_disabled + Setting.request_confrimation_on_registrant_change_enabled = false + new_registrant = contacts(:william).becomes(Registrant) + assert_not_equal new_registrant, @domain.registrant + + request_xml = <<-XML + + + + + + #{@domain.name} + + #{new_registrant.code} + + + + + + #{'test' * 2000} + + + + + XML + + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + @domain.reload + + assert_epp_response :completed_successfully + assert_equal new_registrant, @domain.registrant + assert_not @domain.registrant_verification_asked? + refute_includes @domain.statuses, DomainStatus::PENDING_UPDATE + assert_no_emails + end + + def test_skips_verification_from_current_registrant_when_already_verified_by_registrar + Setting.request_confrimation_on_registrant_change_enabled = true + new_registrant = contacts(:william).becomes(Registrant) + assert_not_equal new_registrant, @domain.registrant + + request_xml = <<-XML + + + + + + #{@domain.name} + + #{new_registrant.code} + + + + + + #{'test' * 2000} + + + + + XML + + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + @domain.reload + + assert_epp_response :completed_successfully + assert_equal new_registrant, @domain.registrant + assert_not @domain.registrant_verification_asked? + refute_includes @domain.statuses, DomainStatus::PENDING_UPDATE + assert_no_emails + end + + def test_clears_force_delete_when_registrar_changed + Setting.request_confrimation_on_registrant_change_enabled = true + new_registrant = contacts(:william).becomes(Registrant) + @domain.schedule_force_delete(type: :fast_track) + assert_not_equal new_registrant, @domain.registrant + assert @domain.force_delete_scheduled? + + request_xml = <<-XML + + + + + + #{@domain.name} + + #{new_registrant.code} + + + + + + #{'test' * 2000} + + + + + XML + + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + @domain.reload + + assert_epp_response :completed_successfully + assert_equal new_registrant, @domain.registrant + assert_not @domain.registrant_verification_asked? + refute @domain.force_delete_scheduled? + refute_includes @domain.statuses, DomainStatus::PENDING_UPDATE + assert_no_emails + end + + def test_deactivates_domain_when_all_name_servers_are_removed + assert @domain.active? + assert_equal 2, @domain.nameservers.count + + request_xml = <<-XML + + + + + + #{@domain.name} + + + + #{nameservers(:shop_ns1).hostname} + + + #{nameservers(:shop_ns2).hostname} + + + + + + + + XML + + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + @domain.reload + + assert_epp_response :completed_successfully + assert @domain.inactive? + end + + def test_update_domain_allows_add_of_client_hold + request_xml = <<-XML + + + + + + shop.test + + Test + + + + + + XML + + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + @domain.reload + assert_epp_response :completed_successfully + assert_includes(@domain.statuses, DomainStatus::CLIENT_HOLD) + end + + def test_update_domain_allows_remove_of_client_hold + @domain.update!(statuses: [DomainStatus::CLIENT_HOLD, DomainStatus::FORCE_DELETE, + DomainStatus::SERVER_RENEW_PROHIBITED, + DomainStatus::SERVER_TRANSFER_PROHIBITED]) + + request_xml = <<-XML + + + + + + shop.test + + Test + + + + + + XML + + post epp_update_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + @domain.reload + assert_epp_response :completed_successfully + assert_not_includes(@domain.statuses, DomainStatus::CLIENT_HOLD) + end + + private + + def assert_verification_and_notification_emails + assert_emails 2 + end +end diff --git a/test/integration/epp/hello_test.rb b/test/integration/epp/hello_test.rb new file mode 100644 index 000000000..b2e03c20b --- /dev/null +++ b/test/integration/epp/hello_test.rb @@ -0,0 +1,18 @@ +require 'test_helper' + +class EppHelloTest < EppTestCase + def test_anonymous_user_is_able_to_access + request_xml = <<-XML + + + + + XML + + get epp_hello_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=non-existent' } + + response_xml = Nokogiri::XML(response.body) + assert_equal 'EPP server (EIS)', response_xml.at_css('greeting > svID').text + end +end diff --git a/test/integration/epp/login/credentials_test.rb b/test/integration/epp/login/credentials_test.rb index 3eac10da5..a62579766 100644 --- a/test/integration/epp/login/credentials_test.rb +++ b/test/integration/epp/login/credentials_test.rb @@ -1,6 +1,6 @@ require 'test_helper' -class EppLoginCredentialsTest < ApplicationIntegrationTest +class EppLoginCredentialsTest < EppTestCase def test_correct_credentials request_xml = <<-XML @@ -17,18 +17,17 @@ class EppLoginCredentialsTest < ApplicationIntegrationTest https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 XML - post '/epp/session/login', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=new_session_id' } + post epp_login_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=new_session_id' } assert EppSession.find_by(session_id: 'new_session_id') assert_equal users(:api_bestnames), EppSession.find_by(session_id: 'new_session_id').user - assert Nokogiri::XML(response.body).at_css('result[code="1000"]') - assert_equal 1, Nokogiri::XML(response.body).css('result').size + assert_epp_response :completed_successfully end def test_already_logged_in @@ -51,14 +50,15 @@ class EppLoginCredentialsTest < ApplicationIntegrationTest https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 XML - post '/epp/session/login', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=any_random_string' } - assert Nokogiri::XML(response.body).at_css('result[code="2501"]') + post epp_login_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=any_random_string' } + + assert_epp_response :authentication_error_server_closing_connection end end diff --git a/test/integration/epp/login/password_change_test.rb b/test/integration/epp/login/password_change_test.rb index 69c3140b6..3b1834406 100644 --- a/test/integration/epp/login/password_change_test.rb +++ b/test/integration/epp/login/password_change_test.rb @@ -1,6 +1,6 @@ require 'test_helper' -class EppLoginPasswordChangeTest < ActionDispatch::IntegrationTest +class EppLoginPasswordChangeTest < EppTestCase def test_password_change request_xml = <<-XML @@ -18,16 +18,15 @@ class EppLoginPasswordChangeTest < ActionDispatch::IntegrationTest https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 XML - post '/epp/session/login', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=new_session_id' } + post epp_login_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=new_session_id' } assert_equal 'new-password', users(:api_bestnames).plain_text_password - assert_equal '1000', Nokogiri::XML(response.body).at_css('result')[:code] - assert_equal 1, Nokogiri::XML(response.body).css('result').size + assert_epp_response :completed_successfully end end \ No newline at end of file diff --git a/test/integration/epp/login/session_limit_test.rb b/test/integration/epp/login/session_limit_test.rb index de7f85a06..f1d83fe7b 100644 --- a/test/integration/epp/login/session_limit_test.rb +++ b/test/integration/epp/login/session_limit_test.rb @@ -1,6 +1,6 @@ require 'test_helper' -class EppLoginSessionLimitTest < ApplicationIntegrationTest +class EppLoginSessionLimitTest < EppTestCase setup do travel_to Time.zone.parse('2010-07-05') EppSession.delete_all @@ -14,11 +14,10 @@ class EppLoginSessionLimitTest < ApplicationIntegrationTest end assert_difference 'EppSession.count' do - post '/epp/session/login', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=new_session_id' } + post epp_login_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=new_session_id' } end - - assert Nokogiri::XML(response.body).at_css('result[code="1000"]') - assert_equal 1, Nokogiri::XML(response.body).css('result').size + assert_epp_response :completed_successfully end def test_reached @@ -29,10 +28,10 @@ class EppLoginSessionLimitTest < ApplicationIntegrationTest end assert_no_difference 'EppSession.count' do - post '/epp/session/login', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=new_session_id' } + post epp_login_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=new_session_id' } end - - assert Nokogiri::XML(response.body).at_css('result[code="2501"]') + assert_epp_response :authentication_error_server_closing_connection end private @@ -53,7 +52,6 @@ class EppLoginSessionLimitTest < ApplicationIntegrationTest https://epp.tld.ee/schema/domain-eis-1.0.xsd https://epp.tld.ee/schema/contact-ee-1.1.xsd urn:ietf:params:xml:ns:host-1.0 - urn:ietf:params:xml:ns:keyrelay-1.0 diff --git a/test/integration/epp/logout_test.rb b/test/integration/epp/logout_test.rb index dc8276e7e..62fa06ca9 100644 --- a/test/integration/epp/logout_test.rb +++ b/test/integration/epp/logout_test.rb @@ -1,25 +1,28 @@ require 'test_helper' -class EppLogoutTest < ApplicationIntegrationTest +class EppLogoutTest < EppTestCase def test_success_response - post '/epp/session/logout', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_bestnames' } - assert Nokogiri::XML(response.body).at_css('result[code="1500"]') - assert_equal 1, Nokogiri::XML(response.body).css('result').size + post epp_logout_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + assert_epp_response :completed_successfully_ending_session end def test_ends_current_session - post '/epp/session/logout', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_bestnames' } + post epp_logout_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } assert_nil EppSession.find_by(session_id: 'api_bestnames') end def test_keeps_other_sessions_intact - post '/epp/session/logout', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_bestnames' } + post epp_logout_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } assert EppSession.find_by(session_id: 'api_goodnames') end def test_anonymous_user - post '/epp/session/logout', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=non-existent' } - assert Nokogiri::XML(response.body).at_css('result[code="2201"]') + post epp_logout_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=non-existent' } + assert_epp_response :authorization_error end private diff --git a/test/integration/epp/poll_test.rb b/test/integration/epp/poll_test.rb index bc3a559cd..c08b0fd9a 100644 --- a/test/integration/epp/poll_test.rb +++ b/test/integration/epp/poll_test.rb @@ -1,6 +1,6 @@ require 'test_helper' -class EppPollTest < ApplicationIntegrationTest +class EppPollTest < EppTestCase setup do @notification = notifications(:complete) end @@ -15,11 +15,11 @@ class EppPollTest < ApplicationIntegrationTest XML - post '/epp/command/poll', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_poll_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } xml_doc = Nokogiri::XML(response.body) - assert_equal 1301.to_s, xml_doc.at_css('result')[:code] - assert_equal 1, xml_doc.css('result').size + assert_epp_response :completed_successfully_ack_to_dequeue assert_equal 2.to_s, xml_doc.at_css('msgQ')[:count] assert_equal @notification.id.to_s, xml_doc.at_css('msgQ')[:id] assert_equal Time.zone.parse('2010-07-05').utc.xmlschema, xml_doc.at_css('msgQ qDate').text @@ -37,7 +37,8 @@ class EppPollTest < ApplicationIntegrationTest XML - post '/epp/command/poll', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_poll_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } xml_doc = Nokogiri::XML(response.body) namespace = 'https://epp.tld.ee/schema/changePoll-1.0.xsd' @@ -61,11 +62,10 @@ class EppPollTest < ApplicationIntegrationTest XML - post '/epp/command/poll', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_poll_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } - xml_doc = Nokogiri::XML(response.body) - assert_equal 1300.to_s, xml_doc.at_css('result')[:code] - assert_equal 1, xml_doc.css('result').size + assert_epp_response :completed_successfully_no_messages end def test_mark_as_read @@ -80,13 +80,13 @@ class EppPollTest < ApplicationIntegrationTest XML - post '/epp/command/poll', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_poll_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } notification.reload xml_doc = Nokogiri::XML(response.body) assert notification.read? - assert_equal 1000.to_s, xml_doc.at_css('result')[:code] - assert_equal 1, xml_doc.css('result').size + assert_epp_response :completed_successfully assert_equal 1.to_s, xml_doc.at_css('msgQ')[:count] assert_equal notification.id.to_s, xml_doc.at_css('msgQ')[:id] end @@ -102,12 +102,12 @@ class EppPollTest < ApplicationIntegrationTest XML - post '/epp/command/poll', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_poll_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } notification.reload - xml_doc = Nokogiri::XML(response.body) assert notification.unread? - assert_equal 2303.to_s, xml_doc.at_css('result')[:code] + assert_epp_response :object_does_not_exist end def test_notification_not_found @@ -119,9 +119,9 @@ class EppPollTest < ApplicationIntegrationTest XML - post '/epp/command/poll', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + post epp_poll_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } - xml_doc = Nokogiri::XML(response.body) - assert_equal 2303.to_s, xml_doc.at_css('result')[:code] + assert_epp_response :object_does_not_exist end -end \ No newline at end of file +end diff --git a/test/integration/registrant_area/contacts_test.rb b/test/integration/registrant_area/contacts_test.rb new file mode 100644 index 000000000..c906cd026 --- /dev/null +++ b/test/integration/registrant_area/contacts_test.rb @@ -0,0 +1,19 @@ +require 'test_helper' + +class RegistrantAreaContactsIntegrationTest < ApplicationIntegrationTest + setup do + @domain = domains(:shop) + @registrant = users(:registrant) + sign_in @registrant + end + + def test_can_view_other_domain_contacts + secondary_contact = contacts(:jane) + + visit registrant_domain_path(@domain) + assert_text secondary_contact.name + click_link secondary_contact.name + assert_text @domain.name + assert_text secondary_contact.email + end +end diff --git a/test/integration/registrant_area/domains_test.rb b/test/integration/registrant_area/domains_test.rb new file mode 100644 index 000000000..d2ca1c775 --- /dev/null +++ b/test/integration/registrant_area/domains_test.rb @@ -0,0 +1,25 @@ +require 'test_helper' + +class RegistrantAreaDomainsIntegrationTest < ApplicationIntegrationTest + setup do + sign_in users(:registrant) + end + + def test_downloads_list_as_csv + get registrant_domains_path(format: :csv) + + assert_response :ok + assert_equal "#{Mime[:csv]}; charset=utf-8", response.headers['Content-Type'] + assert_equal "attachment; filename=\"domains.csv\"; filename*=UTF-8''domains.csv", response.headers['Content-Disposition'] + assert_not_empty response.body + end + + def test_downloads_list_as_pdf + get registrant_domains_path(format: :pdf) + + assert_response :ok + assert_equal Mime[:pdf], response.headers['Content-Type'] + assert_equal "attachment; filename=\"domains.pdf\"; filename*=UTF-8''domains.pdf", response.headers['Content-Disposition'] + assert_not_empty response.body + end +end diff --git a/test/integration/registrant_area/sign_in/id_card_test.rb b/test/integration/registrant_area/sign_in/id_card_test.rb index 68f0d408e..fe6c8a7ef 100644 --- a/test/integration/registrant_area/sign_in/id_card_test.rb +++ b/test/integration/registrant_area/sign_in/id_card_test.rb @@ -6,9 +6,9 @@ class RegistrantAreaIdCardSignInTest < ApplicationIntegrationTest end def test_succeeds - post_via_redirect registrant_id_card_sign_in_path, nil, - 'SSL_CLIENT_S_DN_CN' => 'DOE,JOHN,1234', - 'SSL_CLIENT_I_DN_C' => 'US' + post registrant_id_card_sign_in_path, headers: { 'SSL_CLIENT_S_DN_CN' => 'DOE,JOHN,1234', + 'SSL_CLIENT_I_DN_C' => 'US' } + follow_redirect! assert_response :ok assert_equal registrant_root_path, path @@ -16,7 +16,7 @@ class RegistrantAreaIdCardSignInTest < ApplicationIntegrationTest end def test_fails_when_certificate_is_absent - post_via_redirect registrant_id_card_sign_in_path, nil, 'SSL_CLIENT_S_DN_CN' => '' + post registrant_id_card_sign_in_path, headers: { 'SSL_CLIENT_S_DN_CN' => '' } assert_response :ok assert_equal registrant_id_card_sign_in_path, path diff --git a/test/integration/registrar_area/contacts_test.rb b/test/integration/registrar_area/contacts_test.rb new file mode 100644 index 000000000..a8e50aafa --- /dev/null +++ b/test/integration/registrar_area/contacts_test.rb @@ -0,0 +1,25 @@ +require 'test_helper' + +class RegistrarAreaContactsIntegrationTest < ApplicationIntegrationTest + setup do + sign_in users(:api_bestnames) + end + + def test_downloads_list_as_csv + get registrar_contacts_path(format: :csv) + + assert_response :ok + assert_equal "#{Mime[:csv]}; charset=utf-8", response.headers['Content-Type'] + assert_equal "attachment; filename=\"contacts.csv\"; filename*=UTF-8''contacts.csv", response.headers['Content-Disposition'] + assert_not_empty response.body + end + + def test_downloads_list_as_pdf + get registrar_contacts_path(format: :pdf) + + assert_response :ok + assert_equal Mime[:pdf], response.headers['Content-Type'] + assert_equal "attachment; filename=\"contacts.pdf\"; filename*=UTF-8''contacts.pdf", response.headers['Content-Disposition'] + assert_not_empty response.body + end +end diff --git a/test/integration/registrar_area/domains_test.rb b/test/integration/registrar_area/domains_test.rb new file mode 100644 index 000000000..1a4e0534c --- /dev/null +++ b/test/integration/registrar_area/domains_test.rb @@ -0,0 +1,20 @@ +require 'test_helper' + +class RegistrarAreaDomainsIntegrationTest < ApplicationIntegrationTest + setup do + sign_in users(:api_bestnames) + end + + def test_downloads_list_as_csv + now = Time.zone.parse('2010-07-05 08:00') + travel_to now + + get registrar_domains_path(format: :csv) + + assert_response :ok + assert_equal "#{Mime[:csv]}; charset=utf-8", response.headers['Content-Type'] + assert_equal %(attachment; filename="Domains_#{l(now, format: :filename)}.csv"; filename*=UTF-8''Domains_#{l(now, format: :filename)}.csv), + response.headers['Content-Disposition'] + assert_not_empty response.body + end +end diff --git a/test/system/registrar_area/invoices/payment_callback_test.rb b/test/integration/registrar_area/invoices/payment_callback_test.rb similarity index 57% rename from test/system/registrar_area/invoices/payment_callback_test.rb rename to test/integration/registrar_area/invoices/payment_callback_test.rb index 62cdc1497..94ca6e373 100644 --- a/test/system/registrar_area/invoices/payment_callback_test.rb +++ b/test/integration/registrar_area/invoices/payment_callback_test.rb @@ -1,39 +1,45 @@ require 'test_helper' -class PaymentCallbackTest < ApplicationSystemTestCase +class PaymentCallbackTest < ApplicationIntegrationTest def setup super @user = users(:api_bestnames) sign_in @user + + @payment_order = payment_orders(:everypay_issued) + @invoice = invoices(:one) + @invoice.update!(account_activity: nil, total: 12) end def test_every_pay_callback_returns_status_200 - invoice = payable_invoice - assert_matching_bank_transaction_exists(invoice) - - request_params = every_pay_request_params.merge(invoice_id: invoice.id) - post "/registrar/pay/callback/every_pay", request_params + request_params = every_pay_request_params + post "/registrar/pay/callback/#{@payment_order.id}", params: request_params assert_response :ok end + def test_invoice_is_marked_as_paid + request_params = every_pay_request_params + post "/registrar/pay/callback/#{@payment_order.id}", params: request_params + + assert @payment_order.invoice.paid? + end + + def failure_log_is_created_if_unsuccessful_payment + request_params = every_pay_request_params.dup + request_params['payment_state'] = 'cancelled' + request_params['transaction_result'] = 'failed' + + post "/registrar/pay/callback/#{@payment_order.id}", params: request_params + + @payment_order.reload + assert @payment_order.cancelled? + assert_includes @payment_order.notes, 'Payment state: cancelled' + end + private - def payable_invoice - invoice = invoices(:one) - invoice.update!(account_activity: nil) - invoice - end - - def assert_matching_bank_transaction_exists(invoice) - assert BankTransaction.find_by( - description: invoice.order, - currency: invoice.currency, - iban: invoice.seller_iban - ), 'Matching bank transaction should exist' - end - def every_pay_request_params { nonce: "392f2d7748bc8cb0d14f263ebb7b8932", @@ -56,4 +62,4 @@ class PaymentCallbackTest < ApplicationSystemTestCase payment_method: "every_pay" } end -end \ No newline at end of file +end diff --git a/test/system/registrar_area/invoices/payment_return_test.rb b/test/integration/registrar_area/invoices/payment_return_test.rb similarity index 53% rename from test/system/registrar_area/invoices/payment_return_test.rb rename to test/integration/registrar_area/invoices/payment_return_test.rb index 6ecb69649..a4adb8160 100644 --- a/test/system/registrar_area/invoices/payment_return_test.rb +++ b/test/integration/registrar_area/invoices/payment_return_test.rb @@ -1,6 +1,6 @@ require 'test_helper' -class PaymentReturnTest < ApplicationSystemTestCase +class PaymentReturnTest < ApplicationIntegrationTest def setup super @@ -8,6 +8,9 @@ class PaymentReturnTest < ApplicationSystemTestCase sign_in @user @invoice = invoices(:one) + @invoice.update!(account_activity: nil, total: 12) + @everypay_order = payment_orders(:everypay_issued) + @banklink_order = payment_orders(:banklink_issued) end def every_pay_request_params @@ -57,33 +60,78 @@ class PaymentReturnTest < ApplicationSystemTestCase } end - def test_every_pay_return_creates_activity_redirects_to_invoice_path - request_params = every_pay_request_params.merge(invoice_id: @invoice.id) + def test_successful_bank_payment_marks_invoice_as_paid + @invoice.update!(account_activity: nil) + request_params = bank_link_request_params - post "/registrar/pay/return/every_pay", request_params + post "/registrar/pay/return/#{@banklink_order.id}", params: request_params + + @banklink_order.reload + assert @banklink_order.invoice.paid? + end + + def test_every_pay_return_creates_activity_redirects_to_invoice_path + request_params = every_pay_request_params + + post "/registrar/pay/return/#{@everypay_order.id}", params: request_params assert_equal(302, response.status) assert_redirected_to(registrar_invoice_path(@invoice)) end - def test_Every_Pay_return_raises_RecordNotFound - request_params = every_pay_request_params.merge(invoice_id: "178907") + def test_every_pay_return_raises_record_not_found + request_params = every_pay_request_params assert_raises(ActiveRecord::RecordNotFound) do - post "/registrar/pay/return/every_pay", request_params + post '/registrar/pay/return/123456', params: request_params end end def test_bank_link_return_redirects_to_invoice_paths - request_params = bank_link_request_params.merge(invoice_id: @invoice.id) + request_params = bank_link_request_params - post "/registrar/pay/return/seb", request_params + post "/registrar/pay/return/#{@banklink_order.id}", params: request_params assert_equal(302, response.status) assert_redirected_to(registrar_invoice_path(@invoice)) end def test_bank_link_return - request_params = bank_link_request_params.merge(invoice_id: "178907") + request_params = bank_link_request_params assert_raises(ActiveRecord::RecordNotFound) do - post "/registrar/pay/return/seb", request_params + post '/registrar/pay/return/123456', params: request_params end end + + def test_marks_as_paid_and_adds_notes_if_failed_to_bind + request_params = bank_link_request_params + + post "/registrar/pay/return/#{@banklink_order.id}", params: request_params + post "/registrar/pay/return/#{@banklink_order.id}", params: request_params + @banklink_order.reload + + assert @banklink_order.notes.present? + assert @banklink_order.paid? + assert_includes @banklink_order.notes, 'Failed to bind' + end + + def test_failed_bank_link_payment_creates_brief_error_explanation + request_params = bank_link_request_params.dup + request_params['VK_SERVICE'] = '1911' + + post "/registrar/pay/return/#{@banklink_order.id}", params: request_params + + @banklink_order.reload + + assert_includes @banklink_order.notes, 'Bank responded with code 1911' + end + + def test_failed_every_pay_payment_creates_brief_error_explanation + request_params = every_pay_request_params.dup + request_params['payment_state'] = 'cancelled' + request_params['transaction_result'] = 'failed' + + post "/registrar/pay/return/#{@everypay_order.id}", params: request_params + + @everypay_order.reload + + assert_includes @everypay_order.notes, 'Payment state: cancelled' + end end diff --git a/test/integration/registrar_area/invoices_test.rb b/test/integration/registrar_area/invoices_test.rb index 1f43a5287..91c6afbd8 100644 --- a/test/integration/registrar_area/invoices_test.rb +++ b/test/integration/registrar_area/invoices_test.rb @@ -13,7 +13,7 @@ class RegistrarAreaInvoicesIntegrationTest < ApplicationIntegrationTest assert_response :ok assert_equal 'application/pdf', response.headers['Content-Type'] - assert_equal 'attachment; filename="invoice-1.pdf"', response.headers['Content-Disposition'] + assert_equal "attachment; filename=\"invoice-1.pdf\"; filename*=UTF-8''invoice-1.pdf", response.headers['Content-Disposition'] assert_not_empty response.body end -end \ No newline at end of file +end diff --git a/test/integration/registrar_area/settings/balance_auto_reload_test.rb b/test/integration/registrar_area/settings/balance_auto_reload_test.rb index 2c89630ea..1a2c3f835 100644 --- a/test/integration/registrar_area/settings/balance_auto_reload_test.rb +++ b/test/integration/registrar_area/settings/balance_auto_reload_test.rb @@ -13,8 +13,8 @@ class RegistrarAreaSettingsBalanceAutoReloadIntegrationTest < ActionDispatch::In threshold = 10 assert_nil @registrar.settings['balance_auto_reload'] - patch registrar_settings_balance_auto_reload_path, { type: { amount: amount, - threshold: threshold } } + patch registrar_settings_balance_auto_reload_path, params: { type: { amount: amount, + threshold: threshold } } @registrar.reload assert_equal amount, @registrar.settings['balance_auto_reload']['type']['amount'] diff --git a/test/integration/registrar_area/sign_in/id_card_test.rb b/test/integration/registrar_area/sign_in/id_card_test.rb index 750712f34..1441c90ca 100644 --- a/test/integration/registrar_area/sign_in/id_card_test.rb +++ b/test/integration/registrar_area/sign_in/id_card_test.rb @@ -3,12 +3,18 @@ require 'test_helper' class RegistrarAreaIdCardSignInTest < ApplicationIntegrationTest setup do @user = users(:api_bestnames) + @original_registrar_area_ip_whitelist = Setting.registrar_ip_whitelist_enabled + end + + teardown do + Setting.registrar_ip_whitelist_enabled = @original_registrar_area_ip_whitelist end def test_signs_in_a_user_when_id_card_owner_is_found assert_equal '1234', @user.identity_code - post_via_redirect registrar_id_card_sign_in_path, nil, 'SSL_CLIENT_S_DN_CN' => 'DOE,JOHN,1234' + post registrar_id_card_sign_in_path, headers: { 'SSL_CLIENT_S_DN_CN' => 'DOE,JOHN,1234' } + follow_redirect! assert_response :ok assert_equal registrar_root_path, path @@ -16,8 +22,8 @@ class RegistrarAreaIdCardSignInTest < ApplicationIntegrationTest end def test_does_not_sign_in_a_user_when_id_card_owner_is_not_found - post_via_redirect registrar_id_card_sign_in_path, nil, - 'SSL_CLIENT_S_DN_CN' => 'DOE,JOHN,unacceptable-personal-code' + post registrar_id_card_sign_in_path, + headers: { 'SSL_CLIENT_S_DN_CN' => 'DOE,JOHN,unacceptable-personal-code' } assert_nil controller.current_registrar_user assert_equal registrar_id_card_sign_in_path, path @@ -31,20 +37,18 @@ class RegistrarAreaIdCardSignInTest < ApplicationIntegrationTest Setting.registrar_ip_whitelist_enabled = true - post registrar_id_card_sign_in_path, nil, 'SSL_CLIENT_S_DN_CN' => 'DOE,JOHN,1234', - 'REMOTE_ADDR' => '127.0.0.2' + post registrar_id_card_sign_in_path, headers: { 'SSL_CLIENT_S_DN_CN' => 'DOE,JOHN,1234', + 'REMOTE_ADDR' => '127.0.0.2' } assert_equal registrar_id_card_sign_in_path, path assert_equal 'Access denied from IP 127.0.0.2', response.body get registrar_root_path assert_redirected_to new_registrar_user_session_path - - Setting.registrar_ip_whitelist_enabled = false end def test_does_not_sign_in_a_user_when_certificate_is_absent - post_via_redirect registrar_id_card_sign_in_path, nil, 'SSL_CLIENT_S_DN_CN' => '' + post registrar_id_card_sign_in_path, headers: { 'SSL_CLIENT_S_DN_CN' => '' } assert_nil controller.current_registrar_user assert_equal registrar_id_card_sign_in_path, path diff --git a/test/integration/repp/auctions_test.rb b/test/integration/repp/auctions_test.rb new file mode 100644 index 000000000..145e5d17a --- /dev/null +++ b/test/integration/repp/auctions_test.rb @@ -0,0 +1,23 @@ +require 'test_helper' + +class ReppV1AuctionsTest < ActionDispatch::IntegrationTest + setup do + @auction = auctions(:one) + + @auction.update!(uuid: '1b3ee442-e8fe-4922-9492-8fcb9dccc69c', + domain: 'auction.test', + status: Auction.statuses[:started]) + end + + def test_get_index + get repp_v1_auctions_path + response_json = JSON.parse(response.body, symbolize_names: true) + + assert response_json[:count] == 1 + + expected_response = [{ domain_name: @auction.domain, + punycode_domain_name: @auction.domain }] + + assert_equal expected_response, response_json[:auctions] + end +end diff --git a/test/integration/repp/retained_domains_test.rb b/test/integration/repp/retained_domains_test.rb new file mode 100644 index 000000000..1c9f49f58 --- /dev/null +++ b/test/integration/repp/retained_domains_test.rb @@ -0,0 +1,117 @@ +require 'test_helper' + +class ReppV1RetainedDomainsTest < ActionDispatch::IntegrationTest + # Uses magical fixtures, will fail once fixtures inside are changed: + # test/fixtures/blocked_domains.yml + # test/fixtures/reserved_domains.yml + + def test_get_index + get repp_v1_retained_domains_path + response_json = JSON.parse(response.body, symbolize_names: true) + + assert response_json[:count] == 3 + + expected_objects = [{ name: 'blocked.test', + status: 'blocked', + punycode_name: 'blocked.test' }, + { name: 'blockedäöüõ.test', + status: 'blocked', + punycode_name: 'xn--blocked-cxa7mj0e.test' }, + { name: 'reserved.test', + status: 'reserved', + punycode_name: 'reserved.test' }] + + assert_equal response_json[:domains], expected_objects + end + + def test_get_index_with_type_parameter + get repp_v1_retained_domains_path({ 'type' => 'reserved' }) + response_json = JSON.parse(response.body, symbolize_names: true) + + assert response_json[:count] == 1 + + expected_objects = [{ name: 'reserved.test', + status: 'reserved', + punycode_name: 'reserved.test' }] + + assert_equal response_json[:domains], expected_objects + end + + def test_get_index_disputed_type + dispute = Dispute.new(domain_name: 'disputed.test', starts_at: Time.zone.today, password: 'disputepw') + dispute.save + + get repp_v1_retained_domains_path({ 'type' => 'disputed' }) + response_json = JSON.parse(response.body, symbolize_names: true) + + assert response_json[:count] == 1 + + expected_objects = [{ name: 'disputed.test', + status: 'disputed', + punycode_name: 'disputed.test' }] + + assert_equal response_json[:domains], expected_objects + end + + # A disputed domain can be also reserved, and according + # to business rules it should appear on the list twice. + def test_domain_can_appear_twice_if_it_is_disputed_and_reserved + dispute = Dispute.new(domain_name: 'reserved.test', starts_at: Time.zone.today, password: 'disputepw') + dispute.save + + get repp_v1_retained_domains_path + response_json = JSON.parse(response.body, symbolize_names: true) + + assert response_json[:count] == 4 + + expected_objects = [{ name: 'blocked.test', + status: 'blocked', + punycode_name: 'blocked.test' }, + { name: 'blockedäöüõ.test', + status: 'blocked', + punycode_name: 'xn--blocked-cxa7mj0e.test' }, + { name: 'reserved.test', + status: 'reserved', + punycode_name: 'reserved.test' }, + { name: 'reserved.test', + status: 'disputed', + punycode_name: 'reserved.test' }] + + assert_equal response_json[:domains], expected_objects + end + + def test_etags_cache + get repp_v1_retained_domains_path({ 'type' => 'reserved' }) + etag = response.headers['ETag'] + + get repp_v1_retained_domains_path({ 'type' => 'reserved' }), + headers: { 'If-None-Match' => etag } + + assert_equal response.status, 304 + assert_equal response.body, '' + end + + def test_etags_cache_valid_for_type_only + get repp_v1_retained_domains_path({ 'type' => 'blocked' }) + etag = response.headers['ETag'] + + get repp_v1_retained_domains_path, headers: { 'If-None-Match' => etag } + + assert_equal response.status, 200 + response_json = JSON.parse(response.body, symbolize_names: true) + assert response_json[:count] == 3 + end + + def test_cors_preflight + process :options, repp_v1_retained_domains_path, headers: { 'Origin' => 'https://example.com' } + + assert_equal('https://example.com', response.headers['Access-Control-Allow-Origin']) + assert_equal('POST, GET, PUT, PATCH, DELETE, OPTIONS', + response.headers['Access-Control-Allow-Methods']) + assert_equal('Origin, Content-Type, Accept, Authorization, Token, Auth-Token, Email, ' \ + 'X-User-Token, X-User-Email', + response.headers['Access-Control-Allow-Headers']) + assert_equal('3600', response.headers['Access-Control-Max-Age']) + assert_equal('', response.body) + end +end diff --git a/test/integration/tasks/data_migrations/regenerate_registrar_reference_numbers_test.rb b/test/integration/tasks/data_migrations/regenerate_registrar_reference_numbers_test.rb deleted file mode 100644 index 946c6b898..000000000 --- a/test/integration/tasks/data_migrations/regenerate_registrar_reference_numbers_test.rb +++ /dev/null @@ -1,61 +0,0 @@ -require 'test_helper' - -class RegenerateRegistrarReferenceNumbersTaskTest < ActiveSupport::TestCase - def test_regenerates_registrar_reference_numbers_to_estonian_format - registrar = registrars(:bestnames) - registrar.update_column(:reference_no, 'RF1111') - - capture_io { run_task } - registrar.reload - - assert_not registrar.reference_no.start_with?('RF') - end - - def test_bypasses_registrar_validation - registrar = registrars(:invalid) - registrar.update_column(:reference_no, 'RF1111') - assert registrar.invalid? - - capture_io { run_task } - registrar.reload - - assert_not registrar.reference_no.start_with?('RF') - end - - def test_does_not_regenerate_when_the_task_is_run_again - registrar = registrars(:bestnames) - registrar.update!(reference_no: '1111') - - capture_io { run_task } - registrar.reload - - assert_equal '1111', registrar.reference_no - end - - def test_keeps_iso_reference_number_on_the_invoice_unchanged - registrar = registrars(:bestnames) - registrar.update_column(:reference_no, 'RF1111') - invoice = invoices(:one) - invoice.update!(reference_no: 'RF2222') - - capture_io { run_task } - invoice.reload - - assert_equal 'RF2222', invoice.reference_no - end - - def test_output - registrar = registrars(:bestnames) - registrar.update_column(:reference_no, 'RF1111') - - assert_output "Registrars processed: 1\n" do - run_task - end - end - - private - - def run_task - Rake::Task['data_migrations:regenerate_registrar_reference_numbers'].execute - end -end diff --git a/test/jobs/directo_invoice_forward_job_test.rb b/test/jobs/directo_invoice_forward_job_test.rb new file mode 100644 index 000000000..32ae39e7a --- /dev/null +++ b/test/jobs/directo_invoice_forward_job_test.rb @@ -0,0 +1,154 @@ +require "test_helper" + +class DirectoInvoiceForwardJobTest < ActiveSupport::TestCase + setup do + @invoice = invoices(:one) + @user = registrars(:bestnames) + travel_to Time.zone.parse('2010-08-06') + end + + def teardown + Setting.directo_monthly_number_min = 309901 + Setting.directo_monthly_number_max = 309999 + Setting.directo_monthly_number_last = 309901 + end + + def test_directo_json_sends_customer_as_hash + @invoice.update!(buyer_country_code: @user.address_country_code) + + json_output = @invoice.as_directo_json + assert json_output['customer'].is_a? Hash + assert_equal @user.accounting_customer_code, json_output['customer']['code'] + assert_equal @user.address_country_code, json_output['customer']['destination'] + end + + def test_xml_is_include_transaction_date + @invoice.update(total: @invoice.account_activity.bank_transaction.sum) + @invoice.account_activity.bank_transaction.update(paid_at: Time.zone.now) + + response = <<-XML + + + + + XML + + stub_request(:post, ENV['directo_invoice_url']).with do |request| + request.body.include? 'TransactionDate' + end.to_return(status: 200, body: response) + + assert_nothing_raised do + DirectoInvoiceForwardJob.run(monthly: false, dry: false) + end + + assert_not_empty @invoice.directo_records.first.request + end + + def test_fails_if_directo_bounds_exceedable + activity = account_activities(:one) + price = billing_prices(:create_one_year) + activity.update!(activity_type: 'create', price: price) + + Setting.directo_monthly_number_max = 30991 + + assert_raises 'RuntimeError' do + DirectoInvoiceForwardJob.run(monthly: true, dry: false) + end + end + + def test_monthly_summary_is_delivered_in_estonian + activity = account_activities(:one) + price = billing_prices(:create_one_year) + activity.update!(activity_type: 'create', price: price) + @user.update(language: 'et') + + response = <<-XML + + + + + XML + + stub_request(:post, ENV['directo_invoice_url']).with do |request| + body = CGI.unescape(request.body) + + (body.include? '.test registreerimine: 1 aasta(t)') && + (body.include? 'Domeenide ettemaks') && + (body.include? '309902') + end.to_return(status: 200, body: response) + + assert_difference 'Setting.directo_monthly_number_last' do + DirectoInvoiceForwardJob.run(monthly: true, dry: false) + end + end + + def test_monthly_summary_is_delivered_in_english + activity = account_activities(:one) + price = billing_prices(:create_one_year) + activity.update(activity_type: 'create', price: price) + @user.update(language: 'en') + + response = <<-XML + + + + + XML + + stub_request(:post, ENV['directo_invoice_url']).with do |request| + body = CGI.unescape(request.body) + (body.include? 'test registration') && + (body.include? 'Domains prepayment') && + (body.include? '309902') + end.to_return(status: 200, body: response) + + assert_difference 'Setting.directo_monthly_number_last' do + DirectoInvoiceForwardJob.run(monthly: true, dry: false) + end + end + + def test_multi_year_purchases_have_duration_assigned + activity = account_activities(:one) + price = billing_prices(:create_one_year) + price.update(duration: '3 years') + activity.update(activity_type: 'create', price: price) + + response = <<-XML + + + + + XML + + stub_request(:post, ENV['directo_invoice_url']).with do |request| + body = CGI.unescape(request.body) + (body.include? 'StartDate') && (body.include? 'EndDate') + end.to_return(status: 200, body: response) + + assert_difference 'Setting.directo_monthly_number_last' do + DirectoInvoiceForwardJob.run(monthly: true, dry: false) + end + end + + def test_monthly_duration_products_are_present_in_summary + activity = account_activities(:one) + price = billing_prices(:create_one_month) + activity.update(activity_type: 'create', price: price) + + response = <<-XML + + + + + XML + + stub_request(:post, ENV['directo_invoice_url']).with do |request| + body = CGI.unescape(request.body) + body.include? 'month(s)' + end.to_return(status: 200, body: response) + + assert_difference 'Setting.directo_monthly_number_last' do + DirectoInvoiceForwardJob.run(monthly: true, dry: false) + end + end +end diff --git a/test/jobs/dispute_status_update_job_test.rb b/test/jobs/dispute_status_update_job_test.rb new file mode 100644 index 000000000..e70e58c04 --- /dev/null +++ b/test/jobs/dispute_status_update_job_test.rb @@ -0,0 +1,70 @@ +require "test_helper" + +class DisputeStatusUpdateJobTest < ActiveSupport::TestCase + setup do + travel_to Time.zone.parse('2010-10-05') + @logger = Rails.logger + end + + def test_nothing_is_raised + assert_nothing_raised do + DisputeStatusUpdateJob.run(logger: @logger) + end + end + + def test_whois_data_added_when_dispute_activated + dispute = disputes(:future) + DisputeStatusUpdateJob.run(logger: @logger) + + whois_record = Whois::Record.find_by(name: dispute.domain_name) + assert whois_record.present? + assert_includes whois_record.json['status'], 'disputed' + end + + def test_on_expiry_unregistered_domain_is_sent_to_auction + dispute = disputes(:active) + dispute.update!(starts_at: Time.zone.today - 3.years - 1.day) + + DisputeStatusUpdateJob.run(logger: @logger) + dispute.reload + + assert dispute.closed + + whois_record = Whois::Record.find_by(name: dispute.domain_name) + assert_equal ['AtAuction'], whois_record.json['status'] + end + + def test_registered_domain_whois_data_is_added + Dispute.create(domain_name: 'shop.test', starts_at: '2010-07-05') + travel_to Time.zone.parse('2010-07-05') + DisputeStatusUpdateJob.run(logger: @logger) + + whois_record = Whois::Record.find_by(name: 'shop.test') + assert_includes whois_record.json['status'], 'disputed' + end + + def test_registered_domain_whois_data_is_removed + travel_to Time.zone.parse('2010-07-05') + + domain = domains(:shop) + domain.update(valid_to: Time.zone.parse('2015-07-05').to_s(:db), + outzone_at: Time.zone.parse('2015-07-06').to_s(:db), + delete_date: nil, + force_delete_date: nil) + + # Dispute status is added automatically if starts_at is not in future + Dispute.create(domain_name: 'shop.test', starts_at: Time.zone.parse('2010-07-05')) + domain.reload + + whois_record = Whois::Record.find_by(name: 'shop.test') + assert_includes whois_record.json['status'], 'disputed' + + # Dispute status is removed night time day after it's ended + travel_to Time.zone.parse('2010-07-05') + 3.years + 1.day + + DisputeStatusUpdateJob.run(logger: @logger) + + whois_record.reload + assert_not whois_record.json['status'].include? 'disputed' + end +end diff --git a/test/jobs/domain_delete_confirm_job_test.rb b/test/jobs/domain_delete_confirm_job_test.rb index 51af58c24..b999bd3c7 100644 --- a/test/jobs/domain_delete_confirm_job_test.rb +++ b/test/jobs/domain_delete_confirm_job_test.rb @@ -1,17 +1,11 @@ require "test_helper" class DomainDeleteConfirmJobTest < ActiveSupport::TestCase - def setup - super - + setup do + @legal_doc_path = 'test/fixtures/files/legaldoc.pdf' @domain = domains(:shop) @new_registrant = contacts(:william) @user = users(:api_bestnames) - - @domain.update!(pending_json: { new_registrant_id: @new_registrant.id, - new_registrant_name: @new_registrant.name, - new_registrant_email: @new_registrant.email, - current_user_id: @user.id }) end def teardown @@ -19,6 +13,11 @@ class DomainDeleteConfirmJobTest < ActiveSupport::TestCase end def test_rejected_registrant_verification_notifies_registrar + @domain.update!(pending_json: { new_registrant_id: @new_registrant.id, + new_registrant_name: @new_registrant.name, + new_registrant_email: @new_registrant.email, + current_user_id: @user.id }) + DomainDeleteConfirmJob.enqueue(@domain.id, RegistrantVerification::REJECTED) last_registrar_notification = @domain.registrar.notifications.last @@ -27,10 +26,57 @@ class DomainDeleteConfirmJobTest < ActiveSupport::TestCase end def test_accepted_registrant_verification_notifies_registrar + @domain.update!(pending_json: { new_registrant_id: @new_registrant.id, + new_registrant_name: @new_registrant.name, + new_registrant_email: @new_registrant.email, + current_user_id: @user.id }) + DomainDeleteConfirmJob.enqueue(@domain.id, RegistrantVerification::CONFIRMED) last_registrar_notification = @domain.registrar.notifications.last assert_equal(last_registrar_notification.attached_obj_id, @domain.id) assert_equal(last_registrar_notification.text, 'Registrant confirmed domain deletion: shop.test') end + + def test_marks_domain_as_pending_delete_after_acceptance + epp_xml = "\n\n \n \n" \ + " \n #{@domain.name}\n \n \n \n" \ + " \n #{@legal_doc_path}\n" \ + " \n \n 20alla-1594212240\n \n\n" + + @domain.registrant_verification_asked!(epp_xml, @user.id) + @domain.pending_delete! + @domain.reload + + assert @domain.registrant_delete_confirmable?(@domain.registrant_verification_token) + assert_equal @user.id, @domain.pending_json['current_user_id'] + + DomainDeleteConfirmJob.enqueue(@domain.id, RegistrantVerification::CONFIRMED) + @domain.reload + + assert @domain.statuses.include? DomainStatus::PENDING_DELETE + assert @domain.statuses.include? DomainStatus::SERVER_HOLD + assert_not @domain.statuses.include? DomainStatus::PENDING_DELETE_CONFIRMATION + end + + def test_clears_pending_flags_after_delete_denial + epp_xml = "\n\n \n \n" \ + " \n #{@domain.name}\n \n \n \n" \ + " \n #{@legal_doc_path}\n" \ + " \n \n 20alla-1594212240\n \n\n" + + @domain.registrant_verification_asked!(epp_xml, @user.id) + @domain.pending_delete! + @domain.reload + + assert @domain.registrant_delete_confirmable?(@domain.registrant_verification_token) + assert_equal @user.id, @domain.pending_json['current_user_id'] + + DomainDeleteConfirmJob.enqueue(@domain.id, RegistrantVerification::REJECTED) + @domain.reload + + assert_equal ['ok'], @domain.statuses + assert_not @domain.statuses.include? DomainStatus::PENDING_DELETE_CONFIRMATION + assert_not @domain.statuses.include? DomainStatus::PENDING_DELETE + end end diff --git a/test/jobs/domain_update_confirm_job_test.rb b/test/jobs/domain_update_confirm_job_test.rb index 070b5d5f7..59bbf758d 100644 --- a/test/jobs/domain_update_confirm_job_test.rb +++ b/test/jobs/domain_update_confirm_job_test.rb @@ -7,6 +7,7 @@ class DomainUpdateConfirmJobTest < ActiveSupport::TestCase @domain = domains(:shop) @new_registrant = contacts(:william) @user = users(:api_bestnames) + @legal_doc_path = 'test/fixtures/files/legaldoc.pdf' @domain.update!(pending_json: { new_registrant_id: @new_registrant.id, new_registrant_name: @new_registrant.name, @@ -33,4 +34,34 @@ class DomainUpdateConfirmJobTest < ActiveSupport::TestCase assert_equal(last_registrar_notification.attached_obj_id, @domain.id) assert_equal(last_registrar_notification.text, 'Registrant confirmed domain update: shop.test') end + + def test_changes_domain_registrant_after_approval + epp_xml = "\n\n \n \n \n #{@domain.name}\n" \ + " \n #{@new_registrant.code}\n \n \n \n \n \n" \ + " \n #{@legal_doc_path}\n \n" \ + " \n 20alla-1594199756\n \n\n" + @domain.pending_json['frame'] = epp_xml + @domain.update(pending_json: @domain.pending_json) + + @domain.reload + DomainUpdateConfirmJob.enqueue(@domain.id, RegistrantVerification::CONFIRMED) + @domain.reload + + assert_equal @domain.registrant.code, @new_registrant.code + end + + def test_clears_pending_update_after_denial + epp_xml = "\n\n \n \n \n #{@domain.name}\n" \ + " \n #{@new_registrant.code}\n \n \n \n \n \n" \ + " \n #{@legal_doc_path}\n \n" \ + " \n 20alla-1594199756\n \n\n" + @domain.pending_json['frame'] = epp_xml + @domain.update(pending_json: @domain.pending_json) + + DomainUpdateConfirmJob.enqueue(@domain.id, RegistrantVerification::REJECTED) + @domain.reload + + assert_not @domain.statuses.include? DomainStatus::PENDING_DELETE_CONFIRMATION + assert_not @domain.statuses.include? DomainStatus::PENDING_DELETE + end end diff --git a/test/jobs/regenerate_subzone_whoises_job_test.rb b/test/jobs/regenerate_subzone_whoises_job_test.rb new file mode 100644 index 000000000..6c29e4be7 --- /dev/null +++ b/test/jobs/regenerate_subzone_whoises_job_test.rb @@ -0,0 +1,21 @@ +require 'test_helper' + +class RegenerateSubzoneWhoisesJobTest < ActiveSupport::TestCase + def test_regenerates_whois_data_only_for_subzones + subzone = dns_zones(:one).dup + subzone.origin = 'subzone.test' + subzone.save + + Whois::Record.where(name: subzone.origin).destroy_all + Whois::Record.where(name: dns_zones(:one)).destroy_all + assert_nil Whois::Record.find_by(name: subzone.origin) + assert_nil Whois::Record.find_by(name: dns_zones(:one).origin) + + RegenerateSubzoneWhoisesJob.run + record = Whois::Record.find_by(name: subzone.origin) + assert record + assert record.json['dnssec_keys'].is_a?(Array) + + assert_nil Whois::Record.find_by(name: dns_zones(:one).origin) + end +end diff --git a/test/jobs/send_e_invoice_job_test.rb b/test/jobs/send_e_invoice_job_test.rb new file mode 100644 index 000000000..384479e92 --- /dev/null +++ b/test/jobs/send_e_invoice_job_test.rb @@ -0,0 +1,47 @@ +require 'test_helper' + +class SendEInvoiceJobTest < ActiveSupport::TestCase + + def teardown + EInvoice.provider = EInvoice::Providers::TestProvider.new + EInvoice::Providers::TestProvider.deliveries.clear + end + + def test_if_invoice_is_sended + @invoice = invoices(:one) + EInvoice.provider = EInvoice::Providers::TestProvider.new + EInvoice::Providers::TestProvider.deliveries.clear + + assert_nothing_raised do + SendEInvoiceJob.enqueue(@invoice.id) + end + @invoice.reload + + assert_not @invoice.e_invoice_sent_at.blank? + assert_equal 1, EInvoice::Providers::TestProvider.deliveries.count + end + + def test_if_invoice_sending_retries + @invoice = invoices(:one) + provider_config = { password: nil, + test_mode: true } + EInvoice.provider = EInvoice::Providers::OmnivaProvider.new(provider_config) + stub_request(:get, "https://testfinance.post.ee/finance/erp/erpServices.wsdl").to_timeout + + assert_raise HTTPClient::TimeoutError do + SendEInvoiceJob.enqueue(@invoice.id) + end + assert @invoicee_invoice_sent_at.blank? + + EInvoice.provider = EInvoice::Providers::TestProvider.new + EInvoice::Providers::TestProvider.deliveries.clear + + assert_nothing_raised do + SendEInvoiceJob.enqueue(@invoice.id) + end + @invoice.reload + + assert_not @invoice.e_invoice_sent_at.blank? + assert_equal 1, EInvoice::Providers::TestProvider.deliveries.count + end +end diff --git a/test/jobs/verify_emails_job_test.rb b/test/jobs/verify_emails_job_test.rb new file mode 100644 index 000000000..f55a474db --- /dev/null +++ b/test/jobs/verify_emails_job_test.rb @@ -0,0 +1,59 @@ +require "test_helper" + +class VerifyEmailsJobTest < ActiveSupport::TestCase + def setup + @contact = contacts(:john) + @invalid_contact = contacts(:invalid_email) + @contact_verification = @contact.email_verification + @invalid_contact_verification = @invalid_contact.email_verification + + @default_whitelist = Truemail.configure.whitelisted_domains + @default_blacklist = Truemail.configure.blacklisted_domains + Truemail.configure.whitelisted_domains = whitelisted_domains + Truemail.configure.blacklisted_domains = blacklisted_domains + end + + def teardown + Truemail.configure.whitelisted_domains = @default_whitelist + Truemail.configure.blacklisted_domains = @default_blacklist + end + + def domain(email) + Mail::Address.new(email).domain + rescue Mail::Field::IncompleteParseError + nil + end + + def whitelisted_domains + [domain(@contact.email)].reject(&:blank?) + end + + def blacklisted_domains + [domain(@invalid_contact.email)].reject(&:blank?) + end + + def test_job_checks_if_email_valid + VerifyEmailsJob.run(@contact_verification.id) + @contact_verification.reload + + assert @contact_verification.success + end + + def test_job_checks_does_not_run_if_recent + old_verified_at = Time.zone.now - 10.days + @contact_verification.update(success: true, verified_at: old_verified_at) + assert @contact_verification.recently_verified? + + VerifyEmailsJob.run(@contact_verification.id) + @contact_verification.reload + + assert_in_delta @contact_verification.verified_at.to_i, old_verified_at.to_i, 1 + end + + def test_job_checks_if_email_invalid + VerifyEmailsJob.run(@invalid_contact_verification.id) + @contact_verification.reload + + refute @contact_verification.success + end +end diff --git a/test/learning/paper_trail_test.rb b/test/learning/paper_trail_test.rb index d4c76b026..cecb4f095 100644 --- a/test/learning/paper_trail_test.rb +++ b/test/learning/paper_trail_test.rb @@ -1,6 +1,6 @@ require 'test_helper' -class Post < ActiveRecord::Base +class Post < ApplicationRecord has_paper_trail end @@ -9,7 +9,7 @@ class PaperTrailLearningTest < ActiveSupport::TestCase ActiveRecord::Base.connection.create_table :posts do |t| t.string :title - # Otherwise `touch_with_version` fails silently + # Otherwise `touch` fails silently t.datetime :updated_at end end @@ -21,6 +21,25 @@ class PaperTrailLearningTest < ActiveSupport::TestCase assert_respond_to @record.versions.first, :item_id end + def test_returns_version_count_on_domains + @domain = domains(:airport) + @domain.save + + assert_equal 1, @domain.versions.count + + @domain.name = 'domain.test' + @domain.save! + assert_equal 2, @domain.versions.count + end + + def test_returns_version_count_on_users + @user = users(:registrant) + + @user.email = 'aaa@bbb.com' + @user.save! + assert_equal 1, @user.versions.count + end + def test_creates_new_version_upon_update @record = Post.create!(title: 'old title') original_record = @record.clone @@ -36,11 +55,11 @@ class PaperTrailLearningTest < ActiveSupport::TestCase assert_equal 'update', version.event end - def test_touch_with_version + def test_touch @record = Post.create!(title: 'any') - + assert_difference -> { @record.versions.size } do - @record.touch_with_version + @record.touch end end -end \ No newline at end of file +end diff --git a/test/lib/auth_token/auth_token_creator_test.rb b/test/lib/auth_token/auth_token_creator_test.rb index 0465de9f4..440267a40 100644 --- a/test/lib/auth_token/auth_token_creator_test.rb +++ b/test/lib/auth_token/auth_token_creator_test.rb @@ -47,7 +47,5 @@ class AuthTokenCreatorTest < ActiveSupport::TestCase token_creator_with_defaults = AuthTokenCreator.create_with_defaults(@user) assert_equal(Rails.application.config.secret_key_base, token_creator_with_defaults.key) assert_equal('2010-07-05 02:30:00 UTC', token_creator_with_defaults.expires_at) - - travel_back end end diff --git a/test/lib/auth_token/auth_token_decryptor_test.rb b/test/lib/auth_token/auth_token_decryptor_test.rb index 49ca2b820..e97580a54 100644 --- a/test/lib/auth_token/auth_token_decryptor_test.rb +++ b/test/lib/auth_token/auth_token_decryptor_test.rb @@ -18,12 +18,6 @@ class AuthTokenDecryptorTest < ActiveSupport::TestCase @access_token = "q27NWIsKD5snWj9vZzJ0RcOYvgocEyu7H9yCaDjfmGi54sogovpBeALMPWTZHMcdFQzSiq6b4cI0p5tO0_5UEOHic2jRzNW7mkhi-bn-Y2Wlnw7jhMpxw6VwJR8QEoDzjkcNxnKBN6OKF4nssa60ZQ==" end - def teardown - super - - travel_back - end - def test_decrypt_token_returns_a_hash_when_token_is_valid decryptor = AuthTokenDecryptor.new(@access_token, @key) diff --git a/test/lib/deserializers/xml/contact_test.rb b/test/lib/deserializers/xml/contact_test.rb new file mode 100644 index 000000000..4621efeb2 --- /dev/null +++ b/test/lib/deserializers/xml/contact_test.rb @@ -0,0 +1,114 @@ +require 'test_helper' +require 'deserializers/xml/contact' + +class DeserializersXmlContactTest < ActiveSupport::TestCase + def test_trims_empty_values + xml_string = <<-XML + XML + + nokogiri_frame = Nokogiri::XML(xml_string).remove_namespaces! + instance = ::Deserializers::Xml::Contact.new(nokogiri_frame) + assert_equal instance.call, {} + end + + def test_handles_update + xml_string = <<-XML + + + + + + john-001 + + + new name + Org + + +123.4 + new-email@inbox.test + + + + + + XML + + nokogiri_frame = Nokogiri::XML(xml_string).remove_namespaces! + instance = ::Deserializers::Xml::Contact.new(nokogiri_frame) + assert_equal instance.call, { name: 'new name', + org_name: 'Org', + email: 'new-email@inbox.test', + phone: '+123.4' } + end + + def test_handles_create + name = 'new' + email = 'new@registrar.test' + phone = '+1.2' + + xml_string = <<-XML + + + + + + + #{name} + + #{phone} + #{email} + + + + + any + + + + + XML + + nokogiri_frame = Nokogiri::XML(xml_string).remove_namespaces! + instance = ::Deserializers::Xml::Contact.new(nokogiri_frame) + assert_equal instance.call, { name: 'new', email: 'new@registrar.test', phone: '+1.2' } + end + + def test_handles_statuses + xml_string = <<-XML + + + + + + john-001 + + + new name + + +123.4 + new-email@inbox.test + + + Payment overdue. + + + + + + + + + + XML + + nokogiri_frame = Nokogiri::XML(xml_string).remove_namespaces! + instance = ::Deserializers::Xml::Contact.new(nokogiri_frame) + assert_equal instance.call, { name: 'new name', + email: 'new-email@inbox.test', + phone: '+123.4', + statuses_to_add: ['clientDeleteProhibited', + 'clientUpdateProhibited'], + statuses_to_remove: ['pendingDelete'] + } + end +end diff --git a/test/lib/deserializers/xml/ident_test.rb b/test/lib/deserializers/xml/ident_test.rb new file mode 100644 index 000000000..beff7aef5 --- /dev/null +++ b/test/lib/deserializers/xml/ident_test.rb @@ -0,0 +1,95 @@ +require 'test_helper' +require 'deserializers/xml/ident' + +class DeserializersXmlIdentTest < ActiveSupport::TestCase + def test_returns_empty_hash_when_not_present + xml_string = <<-XML + + + + + + john-001 + + + new name + + +123.4 + new-email@inbox.test + + + + + + XML + + nokogiri_frame = Nokogiri::XML(xml_string).remove_namespaces! + instance = ::Deserializers::Xml::Ident.new(nokogiri_frame) + assert_equal instance.call, {} + end + + def test_returns_empty_hash_when_not_valid + xml_string = <<-XML + + + + + + FIRST0:SH2027223711 + + wrong password + + + + + + 37605030299 + dGVzdCBmYWlsCg== + + + ABC-12345 + + + XML + + nokogiri_frame = Nokogiri::XML(xml_string).remove_namespaces! + instance = ::Deserializers::Xml::Ident.new(nokogiri_frame) + assert_equal instance.call, {} + end + + def test_returns_complete_hash_when_valid + xml_string = <<-XML + + + + + + FIRST0:SH2027223711 + + wrong password + + + + + + 37605030299 + dGVzdCBmYWlsCg== + + + ABC-12345 + + + XML + + nokogiri_frame = Nokogiri::XML(xml_string).remove_namespaces! + instance = ::Deserializers::Xml::Ident.new(nokogiri_frame) + + expected_result = { + ident: '37605030299', + ident_type: 'priv', + ident_country_code: 'EE' + } + + assert_equal instance.call, expected_result + end +end diff --git a/test/lib/deserializers/xml/legal_document_test.rb b/test/lib/deserializers/xml/legal_document_test.rb new file mode 100644 index 000000000..ac173ba4b --- /dev/null +++ b/test/lib/deserializers/xml/legal_document_test.rb @@ -0,0 +1,62 @@ +require 'test_helper' +require 'deserializers/xml/legal_document' + +class DeserializersXmlLegalDocumentTest < ActiveSupport::TestCase + def test_returns_nil_when_required_fields_not_present + xml_string = <<-XML + + + + + + john-001 + + + new name + + +123.4 + new-email@inbox.test + + + + + + XML + + nokogiri_frame = Nokogiri::XML(xml_string).remove_namespaces! + instance = ::Deserializers::Xml::LegalDocument.new(nokogiri_frame) + + assert_nil instance.call + end + + def test_returns_hash_when_document_exists + xml_string = <<-XML + + + + + + FIRST0:SH2027223711 + + wrong password + + + + + + 37605030299 + dGVzdCBmYWlsCg== + + + ABC-12345 + + + XML + + nokogiri_frame = Nokogiri::XML(xml_string).remove_namespaces! + instance = ::Deserializers::Xml::LegalDocument.new(nokogiri_frame) + expected_result = { body: "dGVzdCBmYWlsCg==", type: "pdf" } + + assert_equal expected_result, instance.call + end +end diff --git a/test/lib/serializers/registrant_api/domain_test.rb b/test/lib/serializers/registrant_api/domain_test.rb index 71f234c04..f2623741f 100644 --- a/test/lib/serializers/registrant_api/domain_test.rb +++ b/test/lib/serializers/registrant_api/domain_test.rb @@ -21,7 +21,6 @@ class SerializersRegistrantApiDomainTest < ActiveSupport::TestCase new_json = serializer_for_locked_domain.to_json assert_equal(Time.zone.parse('2010-07-05 10:30'), new_json[:locked_by_registrant_at]) - travel_back end def test_returns_registrar_name @@ -37,11 +36,17 @@ class SerializersRegistrantApiDomainTest < ActiveSupport::TestCase end def test_returns_contacts_name_and_uuid - assert_equal([{name: 'John', id: 'eb2f2766-b44c-4e14-9f16-32ab1a7cb957'}, - {name: 'William', id: '0aa54704-d6f7-4ca9-b8ca-2827d9a4e4eb'}].to_set, + assert_equal([{name: 'John', + id: 'eb2f2766-b44c-4e14-9f16-32ab1a7cb957', + email: 'john@inbox.test'}, + {name: 'William', + id: '0aa54704-d6f7-4ca9-b8ca-2827d9a4e4eb', + email: 'william@inbox.test'}].to_set, @json[:admin_contacts].to_set) - assert_equal([{name: 'William', id: '0aa54704-d6f7-4ca9-b8ca-2827d9a4e4eb'}].to_set, + assert_equal([{name: 'William', + id: '0aa54704-d6f7-4ca9-b8ca-2827d9a4e4eb', + email: 'william@inbox.test'}].to_set, @json[:tech_contacts].to_set) end @@ -71,7 +76,7 @@ class SerializersRegistrantApiDomainTest < ActiveSupport::TestCase def test_other_fields_are_also_present keys = %i[id name registrar registered_at valid_to created_at updated_at registrant tech_contacts admin_contacts transfer_code name_dirty name_puny period - period_unit creator_str updator_str legacy_id legacy_registrar_id legacy_registrant_id + period_unit creator_str updator_str outzone_at delete_date registrant_verification_asked_at registrant_verification_token pending_json force_delete_date statuses locked_by_registrant_at status_notes nameservers] diff --git a/test/mailers/domain_delete_mailer_test.rb b/test/mailers/domain_delete_mailer_test.rb index e6a39ff3d..ae060921f 100644 --- a/test/mailers/domain_delete_mailer_test.rb +++ b/test/mailers/domain_delete_mailer_test.rb @@ -73,9 +73,9 @@ class DomainDeleteMailerTest < ActionMailer::TestCase assert_emails 1 assert_equal ['legal@registry.test'], email.from - assert_equal %w[jane@mail.test john@inbox.test], email.to + assert_equal @domain.force_delete_contact_emails, email.to assert_equal 'Domeen shop.test on kustutusmenetluses' \ ' / Domain shop.test is in deletion process' \ ' / Домен shop.test в процессе удаления', email.subject end -end \ No newline at end of file +end diff --git a/test/mailers/previews/contact_mailer_preview.rb b/test/mailers/previews/contact_mailer_preview.rb index 6186f108a..3d4c4e978 100644 --- a/test/mailers/previews/contact_mailer_preview.rb +++ b/test/mailers/previews/contact_mailer_preview.rb @@ -5,4 +5,4 @@ class ContactMailerPreview < ActionMailer::Preview ContactMailer.email_changed(contact: contact, old_email: 'old@inbox.test') end -end \ No newline at end of file +end diff --git a/test/mailers/previews/registrant_change_mailer_preview.rb b/test/mailers/previews/registrant_change_mailer_preview.rb index dec948fe6..ac3dab2a9 100644 --- a/test/mailers/previews/registrant_change_mailer_preview.rb +++ b/test/mailers/previews/registrant_change_mailer_preview.rb @@ -1,7 +1,11 @@ class RegistrantChangeMailerPreview < ActionMailer::Preview def initialize - @domain = Domain.first - @new_registrant = Registrant.where.not(email: nil, country_code: nil).first + @domain = Domain.joins(:registrant).where.not({ contacts: { email: nil, + country_code: nil, + ident_country_code: nil } }).take + @new_registrant = Registrant.where.not(email: nil, + country_code: nil, + ident_country_code: nil).take super end @@ -21,7 +25,7 @@ class RegistrantChangeMailerPreview < ActionMailer::Preview def accepted RegistrantChangeMailer.accepted(domain: @domain, - old_registrant: @domain.registrar) + old_registrant: @domain.registrant) end def rejected @@ -35,4 +39,4 @@ class RegistrantChangeMailerPreview < ActionMailer::Preview registrar: @domain.registrar, registrant: @domain.registrant) end -end \ No newline at end of file +end diff --git a/test/models/admin_user_test.rb b/test/models/admin_user_test.rb new file mode 100644 index 000000000..aedc911bd --- /dev/null +++ b/test/models/admin_user_test.rb @@ -0,0 +1,142 @@ +require 'test_helper' + +class AdminUserTest < ActiveSupport::TestCase + def test_valid_user_fixture_is_valid + assert valid_user.valid?, proc { valid_user.errors.full_messages } + end + + def test_invalid_without_username + user = valid_user + user.username = '' + assert user.invalid? + end + + def test_invalid_without_password_and_password_confirmation_when_creating + user = valid_non_persisted_user + + user.password = '' + user.password_confirmation = '' + assert user.invalid? + + user.password = valid_password + user.password_confirmation = user.password + assert user.valid? + end + + def test_validates_password_format + user = valid_non_persisted_user + + user.password = 'a' * (Devise.password_length.min.pred) + user.password_confirmation = user.password + assert user.invalid? + + user.password = 'a' * (Devise.password_length.max.next) + user.password_confirmation = user.password + assert user.invalid? + + user.password = 'a' * Devise.password_length.min + user.password_confirmation = user.password + assert user.valid? + + user.password = 'a' * Devise.password_length.max + user.password_confirmation = user.password + assert user.valid? + end + + def test_requires_password_confirmation + user = valid_non_persisted_user + user.password = valid_password + + user.password_confirmation = '' + assert user.invalid? + + user.password_confirmation = 'another' + assert user.invalid? + + user.password_confirmation = user.password + assert user.valid?, proc { user.errors.full_messages } + end + + def test_invalid_without_email + user = valid_user + user.email = '' + assert user.invalid? + end + + def test_validates_email_format + user = valid_user + + user.email = 'invalid' + assert user.invalid? + + user.email = 'valid@registry.test' + assert user.valid? + end + + def test_invalid_when_email_is_already_taken + another_user = valid_user + user = valid_non_persisted_user + + user.email = another_user.email + assert user.invalid? + + user.email = 'new-user@registry.test' + assert user.valid?, proc { user.errors.full_messages } + end + + def test_invalid_without_country_code + user = valid_user + user.country_code = '' + assert user.invalid? + end + + def test_invalid_without_roles + user = valid_user + user.roles = [] + assert user.invalid? + end + + def test_valid_without_identity_code + user = valid_user + user.identity_code = '' + assert user.valid? + end + + def test_invalid_without_identity_code_when_country_code_is_estonia + user = valid_user + user.country_code = 'EE' + + user.identity_code = '' + + assert user.invalid? + end + + # https://en.wikipedia.org/wiki/National_identification_number#Estonia + def test_validates_identity_code_format_when_country_code_is_estonia + user = valid_user + user.country_code = 'EE' + + user.identity_code = '47101010030' + assert user.invalid? + + user.identity_code = '47101010033' + assert user.valid? + end + + private + + def valid_user + users(:admin) + end + + def valid_non_persisted_user + user = valid_user.dup + user.password = user.password_confirmation = valid_password + user.email = 'another@registry.test' + user + end + + def valid_password + 'a' * Devise.password_length.min + end +end diff --git a/test/models/api_user_test.rb b/test/models/api_user_test.rb index 12f434a49..ecbff5cbb 100644 --- a/test/models/api_user_test.rb +++ b/test/models/api_user_test.rb @@ -5,6 +5,53 @@ class ApiUserTest < ActiveSupport::TestCase @user = users(:api_bestnames) end + def test_valid_user_fixture_is_valid + assert valid_user.valid?, proc { valid_user.errors.full_messages } + end + + def test_invalid_without_username + user = valid_user + user.username = '' + assert user.invalid? + end + + def test_invalid_when_username_is_already_taken + user = valid_user + another_user = user.dup + + assert another_user.invalid? + + another_user.username = 'another' + assert another_user.valid? + end + + def test_invalid_without_password + user = valid_user + user.plain_text_password = '' + assert user.invalid? + end + + def test_validates_password_format + user = valid_user + min_length = ApiUser.min_password_length + + user.plain_text_password = 'a' * (min_length.pred) + assert user.invalid? + + user.plain_text_password = 'a' * min_length + assert user.valid? + end + + def test_invalid_without_roles + user = valid_user + user.roles = [] + assert user.invalid? + end + + def test_active_by_default + assert ApiUser.new.active? + end + def test_finds_user_by_id_card id_card = IdCard.new id_card.personal_code = 'one' @@ -15,4 +62,29 @@ class ApiUserTest < ActiveSupport::TestCase @user.update!(identity_code: 'another') assert_nil ApiUser.find_by_id_card(id_card) end -end \ No newline at end of file + + def test_verifies_pki_status + certificate = certificates(:api) + + assert @user.pki_ok?(certificate.crt, certificate.common_name, api: true) + assert_not @user.pki_ok?(certificate.crt, 'invalid-cn', api: true) + + certificate = certificates(:registrar) + + assert @user.pki_ok?(certificate.crt, certificate.common_name, api: false) + assert_not @user.pki_ok?(certificate.crt, 'invalid-cn', api: false) + + certificate.update(revoked: true) + assert_not @user.pki_ok?(certificate.crt, certificate.common_name, api: false) + + certificate = certificates(:api) + certificate.update(revoked: true) + assert_not @user.pki_ok?(certificate.crt, certificate.common_name, api: true) + end + + private + + def valid_user + users(:api_bestnames) + end +end diff --git a/test/models/bank_transaction_test.rb b/test/models/bank_transaction_test.rb index 0e4d88bd6..b8b0f65f7 100644 --- a/test/models/bank_transaction_test.rb +++ b/test/models/bank_transaction_test.rb @@ -6,9 +6,93 @@ class BankTransactionTest < ActiveSupport::TestCase @invoice = invoices(:one) end - def test_matches_against_invoice_number_and_reference_number - create_payable_invoice(number: '2222', total: 10, reference_no: '1111') - transaction = BankTransaction.new(description: 'invoice #2222', sum: 10, reference_no: '1111') + def test_matches_against_invoice_nubmber_and_reference_number + create_payable_invoice(number: '2222', total: 10, reference_no: '1234567') + transaction = BankTransaction.new(description: 'invoice #2222', sum: 10, reference_no: '1234567') + + assert_difference 'AccountActivity.count' do + transaction.autobind_invoice + end + end + + def test_binds_if_this_sum_invoice_already_present + create_payable_invoice(number: '2222', total: 10, reference_no: '1234567') + another_invoice = @invoice.dup + another_invoice.save(validate: false) + another_invoice.update(reference_no: '7654321', number: '2221') + + another_item = @invoice.items.first.dup + another_item.invoice = another_invoice + another_item.save + another_invoice.reload + + first_transaction = BankTransaction.new(description: 'invoice #2221', + sum: 10, + description: 'Order nr 1 from registrar 1234567 second number 2345678') + + first_transaction.create_activity(another_invoice.buyer, another_invoice) + + transaction = BankTransaction.new(description: 'invoice #2222', + sum: 10, + description: 'Order nr 1 from registrar 1234567 second number 2345678') + + assert_difference 'AccountActivity.count' do + transaction.autobind_invoice + end + end + + def test_binds_if_this_sum_cancelled_invoice_already_present + create_payable_invoice(number: '2222', total: 10, reference_no: '1234567') + another_invoice = @invoice.dup + another_invoice.save(validate: false) + + + another_item = @invoice.items.first.dup + another_item.invoice = another_invoice + + another_item.save + another_invoice.reload + another_invoice.update(reference_no: '1234567', number: '2221', cancelled_at: Time.zone.now) + + transaction = BankTransaction.new(description: 'invoice #2222', + sum: 10, + description: 'Order nr 1 from registrar 1234567 second number 2345678') + + assert_difference 'AccountActivity.count' do + transaction.autobind_invoice + end + end + + def test_marks_the_first_one_as_paid_if_same_sum + create_payable_invoice(number: '2222', total: 10, reference_no: '1234567') + another_invoice = @invoice.dup + another_invoice.save(validate: false) + another_invoice.update(reference_no: '7654321', number: '2221') + + another_item = @invoice.items.first.dup + another_item.invoice = another_invoice + another_item.save + another_invoice.reload + + transaction = BankTransaction.new(description: 'invoice #2222', + sum: 10, + description: 'Order nr 1 from registrar 1234567 second number 2345678') + + assert_difference 'AccountActivity.count' do + transaction.autobind_invoice + end + + @invoice.reload + another_invoice.reload + assert(@invoice.paid?) + assert_not(another_invoice.paid?) + end + + def test_matches_against_invoice_nubmber_and_reference_number_in_description + create_payable_invoice(number: '2222', total: 10, reference_no: '1234567') + transaction = BankTransaction.new(description: 'invoice #2222', + sum: 10, + description: 'Order nr 1 from registrar 1234567 second number 2345678') assert_difference 'AccountActivity.count' do transaction.autobind_invoice diff --git a/test/models/billing/price_test.rb b/test/models/billing/price_test.rb new file mode 100644 index 000000000..ccef56910 --- /dev/null +++ b/test/models/billing/price_test.rb @@ -0,0 +1,106 @@ +require 'test_helper' + +class Billing::PriceTest < ActiveSupport::TestCase + setup do + @user = users(:api_bestnames) + end + + def test_valid_price_fixture_is_valid + assert valid_price.valid?, proc { valid_price.errors.full_messages } + end + + def test_invalid_without_price + price = valid_price + price.price = '' + assert price.invalid? + end + + def test_validates_price_format + price = valid_price + + price.price = -1 + assert price.invalid? + + price.price = 0 + assert price.valid?, proc { price.errors.full_messages } + + price.price = "1#{I18n.t('number.currency.format.separator')}1" + assert price.valid? + + price.price = 1 + assert price.valid? + end + + def test_invalid_without_effective_date + price = valid_price + price.valid_from = '' + assert price.invalid? + end + + def test_invalid_without_operation_category + price = valid_price + price.operation_category = '' + assert price.invalid? + end + + def test_validates_operation_category_format + price = valid_price + + price.operation_category = 'invalid' + assert price.invalid? + + price.operation_category = Billing::Price.operation_categories.first + assert price.valid? + end + + def test_invalid_without_duration + price = valid_price + price.duration = '' + assert price.invalid? + end + + def test_validates_duration_format + price = valid_price + + price.duration = 'invalid' + assert price.invalid? + + price.duration = Billing::Price.durations.first + assert price.valid? + end + + def test_returns_operation_categories + operation_categories = %w[create renew] + assert_equal operation_categories, Billing::Price.operation_categories + end + + def test_returns_durations + durations = [ + '3 mons', + '6 mons', + '9 mons', + '1 year', + '2 years', + '3 years', + '4 years', + '5 years', + '6 years', + '7 years', + '8 years', + '9 years', + '10 years', + ] + assert_equal durations, Billing::Price.durations + end + + def test_returns_statuses + statuses = %w[upcoming effective expired] + assert_equal statuses, Billing::Price.statuses + end + + private + + def valid_price + billing_prices(:create_one_month) + end +end diff --git a/test/models/concerns/versions_test.rb b/test/models/concerns/versions_test.rb new file mode 100644 index 000000000..2a54b4476 --- /dev/null +++ b/test/models/concerns/versions_test.rb @@ -0,0 +1,28 @@ +require 'test_helper' + +class VersionsTest < ActiveSupport::TestCase + + def test_if_gets_all_versions_without_error_if_ignored_column_present + @nameserver = nameservers(:shop_ns1) + @nameserver.update(hostname: 'ns99.bestnames.test') + @ignored_column_title = Nameserver.ignored_columns.first + + version = NameserverVersion.last + hash = version.object + hash[@ignored_column_title] = 123456 + version.update(object: hash) + + assert_nothing_raised do + Nameserver.all_versions_for([@nameserver.id], Time.zone.now) + end + end + + def test_if_gets_all_versions_without_error_if_no_ignored_column + @account = accounts(:cash) + @account.update(currency: 'USD') + + assert_nothing_raised do + Account.all_versions_for([@account.id], Time.zone.now) + end + end +end diff --git a/test/models/contact/disclosable_test.rb b/test/models/contact/disclosable_test.rb index 4b944513d..02adfbb08 100644 --- a/test/models/contact/disclosable_test.rb +++ b/test/models/contact/disclosable_test.rb @@ -28,7 +28,7 @@ class ContactDisclosableTest < ActiveSupport::TestCase @contact.disclosed_attributes = %w[some undisclosable] assert @contact.invalid? - assert_includes @contact.errors.get(:disclosed_attributes), 'contain unsupported attribute(s)' + assert_includes @contact.errors[:disclosed_attributes], 'contain unsupported attribute(s)' end def test_valid_when_attribute_is_disclosable diff --git a/test/models/contact/ident_test.rb b/test/models/contact/ident_test.rb new file mode 100644 index 000000000..cc1ea65e9 --- /dev/null +++ b/test/models/contact/ident_test.rb @@ -0,0 +1,128 @@ +require 'test_helper' + +class ContactIdentTest < ActiveSupport::TestCase + def test_valid_ident_is_valid + assert valid_ident.valid?, proc { valid_ident.errors.full_messages } + end + + def test_invalid_without_code + ident = valid_ident + ident.code = '' + assert ident.invalid? + end + + def test_validates_date_of_birth + ident = valid_ident + ident.type = 'birthday' + + ident.code = '2010-07-05' + assert ident.valid? + + ident.code = '2010-07-0' + assert ident.invalid? + end + + # https://en.wikipedia.org/wiki/National_identification_number#Estonia + def test_country_specific_national_id_format_validation + country = Country.new('EE') + ident = valid_ident + ident.type = 'priv' + ident.country_code = country.alpha2 + + ident.code = 'invalid' + assert ident.invalid? + assert_includes ident.errors.full_messages, "Code does not conform to national identification number format of #{country}" + + ident.code = '47101010033' + assert ident.valid? + + ident.country_code = 'US' + ident.code = 'any' + assert ident.valid? + end + + def test_country_specific_company_registration_number_format_validation + country = Country.new('EE') + ident = valid_ident + ident.type = 'org' + ident.country_code = country.alpha2 + allowed_length = 8 + + ident.code = '1' * allowed_length.pred + assert ident.invalid? + assert_includes ident.errors.full_messages, "Code does not conform to registration number format of #{country}" + + ident.code = '1' * allowed_length.next + assert ident.invalid? + + ident.code = '1' * allowed_length + assert ident.valid? + + ident.country_code = 'US' + ident.code = 'any' + assert ident.valid? + end + + def test_invalid_without_type + ident = valid_ident + ident.type = '' + assert ident.invalid? + end + + def test_validates_type + assert_not_includes Contact::Ident.types, 'invalid' + ident = valid_ident + ident.type = 'invalid' + + assert ident.invalid? + end + + def test_invalid_without_country_code + ident = valid_ident + ident.country_code = '' + assert ident.invalid? + end + + def test_validates_country_code_format + ident = valid_ident + + ident.country_code = 'invalid' + assert ident.invalid? + + ident.country_code = 'US' + assert ident.valid? + end + + def test_validates_for_mismatches + ident = valid_ident + mismatch = Contact::Ident::MismatchValidator.mismatches.first + ident.type = mismatch.type + ident.country_code = mismatch.country.alpha2 + + assert ident.invalid? + assert_includes ident.errors.full_messages, %(Ident type "#{ident.type}" is invalid for #{ident.country}) + end + + def test_returns_types + assert_equal %w[org priv birthday], Contact::Ident.types + end + + def test_returns_country + country_code = 'US' + ident = Contact::Ident.new(country_code: country_code) + assert_equal Country.new(country_code), ident.country + end + + def test_equality + assert_equal Contact::Ident.new(code: 'code', type: 'type', country_code: 'US'), + Contact::Ident.new(code: 'code', type: 'type', country_code: 'US') + assert_not_equal Contact::Ident.new(code: 'code', type: 'type', country_code: 'US'), + Contact::Ident.new(code: 'code', type: 'type', country_code: 'GB') + end + + private + + def valid_ident + Contact::Ident.new(code: '1234', type: 'priv', country_code: 'US') + end +end diff --git a/test/models/contact_test.rb b/test/models/contact_test.rb index 2e0a463ec..bbbafc511 100644 --- a/test/models/contact_test.rb +++ b/test/models/contact_test.rb @@ -3,10 +3,15 @@ require 'test_helper' class ContactTest < ActiveSupport::TestCase setup do @contact = contacts(:john) + @old_validation_type = Truemail.configure.default_validation_type end - def test_valid_fixture_is_valid - assert @contact.valid?, proc { @contact.errors.full_messages } + teardown do + Truemail.configure.default_validation_type = @old_validation_type + end + + def test_valid_contact_fixture_is_valid + assert valid_contact.valid?, proc { valid_contact.errors.full_messages } end def test_invalid_fixture_is_invalid @@ -21,33 +26,134 @@ class ContactTest < ActiveSupport::TestCase assert_equal 'org', Contact::ORG end - def test_invalid_without_email - @contact.email = '' - assert @contact.invalid? + def test_invalid_without_name + contact = valid_contact + contact.name = '' + assert contact.invalid? end - def test_email_format_validation - @contact.email = 'invalid' - assert @contact.invalid? + def test_validates_code_format + contact = valid_contact.dup + max_length = 100 - @contact.email = 'test@bestmail.test' - assert @contact.valid? + contact.code = '!invalid' + assert contact.invalid? + + contact.code = 'a' * max_length.next + assert contact.invalid? + + contact.code = 'foo:bar' + assert contact.valid? + + contact.code = 'a' * max_length + assert contact.valid? + end + + def test_invalid_when_code_is_already_taken + another_contact = valid_contact + contact = another_contact.dup + + contact.code = another_contact.code + assert contact.invalid? + + contact.regenerate_code + assert contact.valid? + end + + def test_invalid_without_email + contact = valid_contact + contact.email = '' + assert contact.invalid? + end + + def test_email_verification_valid + contact = valid_contact + contact.email = 'info@internet.ee' + assert contact.valid? + end + + def test_email_verification_smtp_error + Truemail.configure.default_validation_type = :smtp + + contact = valid_contact + contact.email = 'somecrude1337joke@internet.ee' + assert contact.invalid? + assert_equal I18n.t('activerecord.errors.models.contact.attributes.email.email_smtp_check_error'), contact.errors.messages[:email].first + end + + def test_email_verification_mx_error + Truemail.configure.default_validation_type = :mx + + contact = valid_contact + contact.email = 'somecrude31337joke@somestrange31337domain.ee' + assert contact.invalid? + assert_equal I18n.t('activerecord.errors.models.contact.attributes.email.email_mx_check_error'), contact.errors.messages[:email].first + end + + def test_email_verification_regex_error + Truemail.configure.default_validation_type = :regex + + contact = valid_contact + contact.email = 'some@strangesentence@internet.ee' + assert contact.invalid? + assert_equal I18n.t('activerecord.errors.models.contact.attributes.email.email_regex_check_error'), contact.errors.messages[:email].first end def test_invalid_without_phone - @contact.email = '' - assert @contact.invalid? + contact = valid_contact + contact.phone = '' + assert contact.invalid? end - def test_phone_format_validation - @contact.phone = '+123.' - assert @contact.invalid? + # https://en.wikipedia.org/wiki/E.164 + def test_validates_phone_format + contact = valid_contact - @contact.phone = '+123.4' - assert @contact.valid? + contact.phone = '+.1' + assert contact.invalid? + + contact.phone = '+123.' + assert contact.invalid? + + contact.phone = '+1.123456789123456' + assert contact.invalid? + + contact.phone = '+134.1234567891234' + assert contact.invalid? + + contact.phone = '+000.1' + assert contact.invalid? + + contact.phone = '+123.0' + assert contact.invalid? + + contact.phone = '+1.2' + assert contact.valid? + + contact.phone = '+123.4' + assert contact.valid? + + contact.phone = '+1.12345678912345' + assert contact.valid? + + contact.phone = '+134.123456789123' + assert contact.valid? + end + + def test_valid_without_address_when_address_processing_id_disabled + contact = valid_contact + + contact.street = '' + contact.city = '' + contact.zip = '' + contact.country_code = '' + + assert contact.valid? end def test_address + Setting.address_processing = true + address = Contact::Address.new('new street', '83746', 'new city', 'new state', 'EE') @contact.address = address @contact.save! @@ -74,13 +180,12 @@ class ContactTest < ActiveSupport::TestCase end def test_returns_registrant_user_indirect_contacts - @contact.update!(ident_type: Contact::ORG) - assert_equal '1234', @contact.ident + @contact.update!(ident_type: Contact::ORG, ident: '1234321') assert_equal 'US', @contact.ident_country_code - registrant_user = RegistrantUser.new(registrant_ident: 'US-1234') + registrant_user = RegistrantUser.new(registrant_ident: 'US-1234321') - registrant_user.stub(:companies, [OpenStruct.new(registration_number: '1234')]) do - assert_equal [@contact], Contact.registrant_user_contacts(registrant_user) + registrant_user.stub(:companies, [OpenStruct.new(registration_number: '1234321')]) do + assert_equal registrant_user.contacts, Contact.registrant_user_contacts(registrant_user) end end @@ -93,15 +198,15 @@ class ContactTest < ActiveSupport::TestCase end def test_linked_when_in_use_as_registrant - Domain.update_all(registrant_id: @contact) + Domain.update_all(registrant_id: @contact.id) DomainContact.delete_all assert @contact.linked? end def test_linked_when_in_use_as_domain_contact - Domain.update_all(registrant_id: contacts(:william)) - DomainContact.update_all(contact_id: @contact) + Domain.update_all(registrant_id: contacts(:william).id) + DomainContact.first.update(contact_id: @contact.id) assert @contact.linked? end @@ -179,21 +284,83 @@ class ContactTest < ActiveSupport::TestCase assert Contact.unlinked.exclude?(contact), 'Contact should be excluded' end + def test_normalizes_country_code + Setting.address_processing = true + contact = Contact.new(country_code: 'us') + contact.validate + assert_equal 'US', contact.country_code + end + + def test_normalizes_ident_country_code + contact = Contact.new(ident_country_code: 'us') + contact.validate + assert_equal 'US', contact.ident_country_code + end + + def test_generates_code + contact = Contact.new(registrar: registrars(:bestnames)) + assert_nil contact.code + + contact.generate_code + + assert_not_empty contact.code + end + + def test_prohibits_code_change + assert_no_changes -> { @contact.code } do + @contact.code = 'new' + @contact.save! + @contact.reload + end + end + + def test_removes_duplicate_statuses + contact = Contact.new(statuses: %w[ok ok]) + assert_equal %w[ok], contact.statuses + end + + def test_default_status + contact = Contact.new + assert_equal %w[ok], contact.statuses + end + + def test_whois_gets_updated_after_contact_save + @contact.name = 'SomeReallyWeirdRandomTestName' + domain = @contact.registrant_domains.first + + @contact.save! + + assert_equal domain.whois_record.try(:json).try(:[], 'registrant'), @contact.name + end + + def test_creates_email_verification_in_unicode + unicode_email = 'suur@äri.ee' + punycode_email = Contact.unicode_to_punycode(unicode_email) + + @contact.email = punycode_email + @contact.save + + assert_equal @contact.email_verification.email, unicode_email + end + private def make_contact_free_of_domains_where_it_acts_as_a_registrant(contact) other_contact = contacts(:william) assert_not_equal other_contact, contact - Domain.update_all(registrant_id: other_contact) + Domain.update_all(registrant_id: other_contact.id) end def unlinked_contact other_contact = contacts(:william) assert_not_equal @contact, other_contact - Domain.update_all(registrant_id: other_contact) - + Domain.update_all(registrant_id: other_contact.id) DomainContact.delete_all @contact end -end \ No newline at end of file + + def valid_contact + contacts(:john) + end +end diff --git a/test/models/deposit_test.rb b/test/models/deposit_test.rb index b7510b960..171316f65 100644 --- a/test/models/deposit_test.rb +++ b/test/models/deposit_test.rb @@ -5,14 +5,12 @@ class DepositTest < ActiveSupport::TestCase super @deposit = Deposit.new(registrar: registrars(:bestnames)) - @minimum_deposit = Setting.minimum_deposit + @original_minimum_deposit = Setting.minimum_deposit Setting.minimum_deposit = 1.00 end - def teardown - super - - Setting.minimum_deposit = @minimum_deposit + teardown do + Setting.minimum_deposit = @original_minimum_deposit end def test_validate_amount_cannot_be_lower_than_0_01 @@ -38,22 +36,22 @@ class DepositTest < ActiveSupport::TestCase def test_amount_is_converted_from_string @deposit.amount = "12.00" - assert_equal(BigDecimal.new("12.00"), @deposit.amount) + assert_equal(BigDecimal("12.00"), @deposit.amount) @deposit.amount = "12,11" - assert_equal(BigDecimal.new("12.11"), @deposit.amount) + assert_equal(BigDecimal("12.11"), @deposit.amount) end def test_amount_is_converted_from_float @deposit.amount = 12.0044 - assert_equal(BigDecimal.new("12.0044"), @deposit.amount) + assert_equal(BigDecimal("12.0044"), @deposit.amount) @deposit.amount = 12.0144 - assert_equal(BigDecimal.new("12.0144"), @deposit.amount) + assert_equal(BigDecimal("12.0144"), @deposit.amount) end def test_amount_is_converted_from_nil @deposit.amount = nil - assert_equal(BigDecimal.new("0.00"), @deposit.amount) + assert_equal(BigDecimal("0.00"), @deposit.amount) end end diff --git a/test/models/directo_test.rb b/test/models/directo_test.rb new file mode 100644 index 000000000..603a38d15 --- /dev/null +++ b/test/models/directo_test.rb @@ -0,0 +1,4 @@ +require 'test_helper' + +class DirectoTest < ActiveSupport::TestCase +end diff --git a/test/models/disputed_domain_test.rb b/test/models/disputed_domain_test.rb new file mode 100644 index 000000000..01897e19b --- /dev/null +++ b/test/models/disputed_domain_test.rb @@ -0,0 +1,52 @@ +require 'test_helper' + +class DisputedDomainTest < ActiveSupport::TestCase + setup do + @dispute = disputes(:active) + end + + def test_fixture_is_valid + assert @dispute.valid? + end + + def test_can_be_closed_by_domain_name + travel_to Time.zone.parse('2010-10-05') + + Dispute.close_by_domain(@dispute.domain_name) + @dispute.reload + + assert @dispute.closed + end + + def test_syncs_password_to_reserved + dispute = Dispute.new(domain_name: 'reserved.test', starts_at: Time.zone.today, password: 'disputepw') + dispute.save + dispute.reload + assert_equal dispute.password, ReservedDomain.find_by(name: dispute.domain_name).password + end + + def test_domain_name_zone_is_validated + dispute = Dispute.new(domain_name: 'correct.test', starts_at: Time.zone.today) + assert dispute.valid? + + dispute.domain_name = 'zone.is.unrecognized.test' + assert_not dispute.valid? + end + + def test_dispute_can_not_be_created_if_another_active_is_present + dispute = Dispute.new(domain_name: @dispute.domain_name, + starts_at: @dispute.starts_at + 1.day) + assert_not dispute.valid? + end + + def test_expires_at_date_is_appended_automatically + dispute = Dispute.new(domain_name: 'random.test', starts_at: Time.zone.today) + assert dispute.valid? + assert_equal dispute.expires_at, dispute.starts_at + 3.years + end + + def test_starts_at_must_be_present + dispute = Dispute.new(domain_name: 'random.test') + assert_not dispute.valid? + end +end diff --git a/test/models/dns/domain_name_test.rb b/test/models/dns/domain_name_test.rb index 5d0dd5386..4f8922d32 100644 --- a/test/models/dns/domain_name_test.rb +++ b/test/models/dns/domain_name_test.rb @@ -13,6 +13,8 @@ class AuctionDoubleTest < ActiveSupport::TestCase end class DNS::DomainNameTest < ActiveSupport::TestCase + fixtures 'whois/records' + def test_available_when_not_at_auction domain_name = DNS::DomainName.new('auction.test') auctions(:one).update!(domain: 'auction.test', status: Auction.statuses[:domain_registered]) @@ -131,7 +133,10 @@ class DNS::DomainNameTest < ActiveSupport::TestCase def test_blocked assert_equal 'blocked.test', blocked_domains(:one).name + assert_equal 'blockedäöüõ.test', blocked_domains(:idn).name assert DNS::DomainName.new('blocked.test').blocked? + assert DNS::DomainName.new('blockedäöüõ.test').blocked? + assert DNS::DomainName.new(SimpleIDN.to_ascii('blockedäöüõ.test')).blocked? assert_not DNS::DomainName.new('nonblocked .test').blocked? end diff --git a/test/models/dns/zone_test.rb b/test/models/dns/zone_test.rb new file mode 100644 index 000000000..fab4c6355 --- /dev/null +++ b/test/models/dns/zone_test.rb @@ -0,0 +1,186 @@ +require 'test_helper' + +class DNS::ZoneTest < ActiveSupport::TestCase + def test_valid_zone_fixture_is_valid + assert valid_zone.valid?, proc { valid_zone.errors.full_messages } + end + + def test_invalid_without_origin + zone = valid_zone + zone.origin = '' + assert zone.invalid? + end + + def test_invalid_when_origin_is_already_taken + zone = valid_zone + another_zone = zone.dup + assert another_zone.invalid? + end + + def test_invalid_without_ttl + zone = valid_zone + zone.ttl = '' + assert zone.invalid? + end + + def test_validates_ttl_format + zone = valid_zone + + zone.ttl = 'text' + assert zone.invalid? + + zone.ttl = '1.1' + assert zone.invalid? + + zone.ttl = '1' + assert zone.valid? + end + + def test_invalid_without_refresh + zone = valid_zone + zone.refresh = '' + assert zone.invalid? + end + + def test_validates_refresh_format + zone = valid_zone + + zone.refresh = 'text' + assert zone.invalid? + + zone.refresh = '1.1' + assert zone.invalid? + + zone.refresh = '1' + assert zone.valid? + end + + def test_invalid_without_retry + zone = valid_zone + zone.retry = '' + assert zone.invalid? + end + + def test_validates_retry_format + zone = valid_zone + + zone.retry = 'text' + assert zone.invalid? + + zone.retry = '1.1' + assert zone.invalid? + + zone.retry = '1' + assert zone.valid? + end + + def test_invalid_without_expire + zone = valid_zone + zone.expire = '' + assert zone.invalid? + end + + def test_validates_expire_format + zone = valid_zone + + zone.expire = 'text' + assert zone.invalid? + + zone.expire = '1.1' + assert zone.invalid? + + zone.expire = '1' + assert zone.valid? + end + + def test_invalid_without_minimum_ttl + zone = valid_zone + zone.minimum_ttl = '' + assert zone.invalid? + end + + def test_validates_minimum_ttl_format + zone = valid_zone + + zone.minimum_ttl = 'text' + assert zone.invalid? + + zone.minimum_ttl = '1.1' + assert zone.invalid? + + zone.minimum_ttl = '1' + assert zone.valid? + end + + def test_invalid_without_email + zone = valid_zone + zone.email = '' + assert zone.invalid? + end + + def test_invalid_without_master_nameserver + zone = valid_zone + zone.master_nameserver = '' + assert zone.invalid? + end + + def test_determines_if_subzone + zone = valid_zone + zone.update(origin: 'pri.ee') + assert zone.subzone? + end + + def test_updates_whois_after_update + subzone = dns_zones(:one).dup + + subzone.origin = 'sub.zone' + subzone.save + + whois_record = Whois::Record.find_by(name: subzone.origin) + assert whois_record.present? + end + + def test_has_setting_info_as_contacts_for_subzones + subzone = dns_zones(:one).dup + + subzone.origin = 'sub.zone' + subzone.save + + whois_record = Whois::Record.find_by(name: subzone.origin) + assert whois_record.present? + + assert_equal Setting.registry_whois_disclaimer, whois_record.json['disclaimer'] + assert_equal Setting.registry_email, whois_record.json['email'] + assert_equal Setting.registry_juridical_name, whois_record.json['registrar'] + assert_equal Setting.registry_url, whois_record.json['registrar_website'] + assert_equal Setting.registry_phone, whois_record.json['registrar_phone'] + + assert_equal Setting.registry_juridical_name, whois_record.json['registrant'] + assert_equal Setting.registry_reg_no, whois_record.json['registrant_reg_no'] + assert_equal Setting.registry_country_code, whois_record.json['registrant_ident_country_code'] + + contact = { name: Setting.registry_invoice_contact, email: Setting.registry_email, + disclosed_attributes: %w[name email] }.with_indifferent_access + + assert_equal contact, whois_record.json['admin_contacts'][0] + assert_equal contact, whois_record.json['tech_contacts'][0] + end + + def test_deletes_whois_record_after_destroy + subzone = dns_zones(:one).dup + + subzone.origin = 'sub.zone' + subzone.save + + assert Whois::Record.find_by(name: subzone.origin).present? + + subzone.destroy + assert_nil Whois::Record.find_by(name: subzone.origin) + end + + private + + def valid_zone + dns_zones(:one) + end +end diff --git a/test/models/domain/domain_version_test.rb b/test/models/domain/domain_version_test.rb index 74844f3af..2139c21c1 100644 --- a/test/models/domain/domain_version_test.rb +++ b/test/models/domain/domain_version_test.rb @@ -16,7 +16,7 @@ class DomainVersionTest < ActiveSupport::TestCase def test_assigns_creator_to_paper_trail_whodunnit duplicate_domain = prepare_duplicate_domain - PaperTrail.whodunnit = @user.id_role_username + PaperTrail.request.whodunnit = @user.id_role_username assert_difference 'duplicate_domain.versions.count', 1 do duplicate_domain.save! end @@ -28,7 +28,7 @@ class DomainVersionTest < ActiveSupport::TestCase end def test_assigns_updator_to_paper_trail_whodunnit - PaperTrail.whodunnit = @user.id_role_username + PaperTrail.request.whodunnit = @user.id_role_username assert_difference '@domain.versions.count', 1 do @domain.apply_registry_lock diff --git a/test/models/domain/force_delete_test.rb b/test/models/domain/force_delete_test.rb index 9092fad86..e3818c484 100644 --- a/test/models/domain/force_delete_test.rb +++ b/test/models/domain/force_delete_test.rb @@ -1,37 +1,70 @@ require 'test_helper' -class DomainForceDeleteTest < ActiveSupport::TestCase +class NewDomainForceDeleteTest < ActiveSupport::TestCase setup do @domain = domains(:shop) - @original_redemption_grace_period = Setting.redemption_grace_period - end - - teardown do - Setting.redemption_grace_period = @original_redemption_grace_period - end - - def test_schedules_force_delete - assert_not @domain.force_delete_scheduled? Setting.redemption_grace_period = 30 + end + + def test_schedules_force_delete_fast_track + assert_not @domain.force_delete_scheduled? travel_to Time.zone.parse('2010-07-05') - @domain.schedule_force_delete + @domain.schedule_force_delete(type: :fast_track) @domain.reload assert @domain.force_delete_scheduled? - assert_equal Date.parse('2010-08-05'), @domain.force_delete_date + assert_equal Date.parse('2010-08-20'), @domain.force_delete_date.to_date + assert_equal Date.parse('2010-07-06'), @domain.force_delete_start.to_date end - def test_scheduling_force_delete_adds_corresponding_statuses + def test_schedules_force_delete_soft_year_ahead + @domain.update(valid_to: Time.zone.parse('2012-08-05')) + assert_not @domain.force_delete_scheduled? + travel_to Time.zone.parse('2010-07-05') + + @domain.schedule_force_delete(type: :soft) + @domain.reload + + assert @domain.force_delete_scheduled? + assert_equal Date.parse('2010-09-20'), @domain.force_delete_date.to_date + assert_equal Date.parse('2010-08-06'), @domain.force_delete_start.to_date + end + + def test_schedules_force_delete_soft_less_than_year_ahead + @domain.update_columns(valid_to: Time.zone.parse('2010-08-05'), + force_delete_date: nil) + assert_not @domain.force_delete_scheduled? + travel_to Time.zone.parse('2010-07-05') + + @domain.schedule_force_delete(type: :soft) + @domain.reload + + assert @domain.force_delete_scheduled? + assert_nil @domain.force_delete_date + assert_nil @domain.force_delete_start + end + + def test_scheduling_soft_force_delete_adds_corresponding_statuses statuses_to_be_added = [ DomainStatus::FORCE_DELETE, DomainStatus::SERVER_RENEW_PROHIBITED, DomainStatus::SERVER_TRANSFER_PROHIBITED, - DomainStatus::SERVER_UPDATE_PROHIBITED, - DomainStatus::PENDING_DELETE, ] - @domain.schedule_force_delete + @domain.schedule_force_delete(type: :soft) + @domain.reload + assert (@domain.statuses & statuses_to_be_added) == statuses_to_be_added + end + + def test_scheduling_fast_track_force_delete_adds_corresponding_statuses + statuses_to_be_added = [ + DomainStatus::FORCE_DELETE, + DomainStatus::SERVER_RENEW_PROHIBITED, + DomainStatus::SERVER_TRANSFER_PROHIBITED, + ] + + @domain.schedule_force_delete(type: :fast_track) @domain.reload assert (@domain.statuses & statuses_to_be_added) == statuses_to_be_added end @@ -43,12 +76,13 @@ class DomainForceDeleteTest < ActiveSupport::TestCase ] @domain.statuses = statuses_to_be_removed + %w[other-status] - @domain.schedule_force_delete + @domain.schedule_force_delete(type: :fast_track) @domain.reload assert_empty @domain.statuses & statuses_to_be_removed end def test_scheduling_force_delete_stops_pending_actions + Setting.redemption_grace_period = 45 statuses_to_be_removed = [ DomainStatus::PENDING_UPDATE, DomainStatus::PENDING_TRANSFER, @@ -57,33 +91,35 @@ class DomainForceDeleteTest < ActiveSupport::TestCase ] @domain.statuses = statuses_to_be_removed + %w[other-status] - @domain.schedule_force_delete + @domain.schedule_force_delete(type: :fast_track) @domain.reload assert_empty @domain.statuses & statuses_to_be_removed, 'Pending actions should be stopped' end def test_scheduling_force_delete_preserves_current_statuses @domain.statuses = %w[test1 test2] - @domain.schedule_force_delete + @domain.schedule_force_delete(type: :fast_track) @domain.reload assert_equal %w[test1 test2], @domain.statuses_before_force_delete end def test_scheduling_force_delete_bypasses_validation @domain = domains(:invalid) - @domain.schedule_force_delete + @domain.schedule_force_delete(type: :fast_track) assert @domain.force_delete_scheduled? end def test_force_delete_cannot_be_scheduled_when_a_domain_is_discarded @domain.update!(statuses: [DomainStatus::DELETE_CANDIDATE]) assert_raises StandardError do - @domain.schedule_force_delete + @domain.schedule_force_delete(type: :fast_track) end end def test_cancels_force_delete - @domain.update_columns(statuses: [DomainStatus::FORCE_DELETE], force_delete_date: '2010-07-05') + @domain.update_columns(statuses: [DomainStatus::FORCE_DELETE], + force_delete_date: Time.zone.parse('2010-07-05'), + force_delete_start: Time.zone.parse('2010-07-05') - 45.days) assert @domain.force_delete_scheduled? @domain.cancel_force_delete @@ -91,11 +127,12 @@ class DomainForceDeleteTest < ActiveSupport::TestCase assert_not @domain.force_delete_scheduled? assert_nil @domain.force_delete_date + assert_nil @domain.force_delete_start end def test_cancelling_force_delete_bypasses_validation @domain = domains(:invalid) - @domain.schedule_force_delete + @domain.schedule_force_delete(type: :fast_track) @domain.cancel_force_delete assert_not @domain.force_delete_scheduled? end @@ -105,12 +142,9 @@ class DomainForceDeleteTest < ActiveSupport::TestCase DomainStatus::FORCE_DELETE, DomainStatus::SERVER_RENEW_PROHIBITED, DomainStatus::SERVER_TRANSFER_PROHIBITED, - DomainStatus::SERVER_UPDATE_PROHIBITED, - DomainStatus::PENDING_DELETE, - DomainStatus::SERVER_MANUAL_INZONE ] @domain.statuses = @domain.statuses + statuses - @domain.schedule_force_delete + @domain.schedule_force_delete(type: :fast_track) @domain.cancel_force_delete @domain.reload @@ -118,13 +152,94 @@ class DomainForceDeleteTest < ActiveSupport::TestCase assert_empty @domain.statuses & statuses end - def test_cancelling_force_delete_restores_statuses_that_a_domain_had_before_force_delete - @domain.statuses_before_force_delete = ['test1', DomainStatus::DELETE_CANDIDATE] - - @domain.cancel_force_delete + def test_hard_force_delete_should_have_outzone_and_purge_date_with_time + @domain.schedule_force_delete(type: :fast_track) @domain.reload - assert_equal ['test1', DomainStatus::DELETE_CANDIDATE], @domain.statuses - assert_nil @domain.statuses_before_force_delete + assert_equal(@domain.purge_date.to_date, @domain.force_delete_date) + assert_equal(@domain.outzone_date.to_date, @domain.force_delete_start.to_date + + Setting.expire_warning_period.days) + assert(@domain.purge_date.is_a?(ActiveSupport::TimeWithZone)) + assert(@domain.outzone_date.is_a?(ActiveSupport::TimeWithZone)) + end + + def test_soft_force_delete_year_ahead_should_have_outzone_and_purge_date_with_time + @domain.update(valid_to: Time.zone.parse('2012-08-05')) + @domain.update(template_name: 'legal_person') + travel_to Time.zone.parse('2010-07-05') + + @domain.schedule_force_delete(type: :soft) + + travel_to Time.zone.parse('2010-08-21') + DomainCron.start_client_hold + @domain.reload + + assert_equal(@domain.purge_date.to_date, @domain.force_delete_date.to_date) + assert_equal(@domain.outzone_date.to_date, @domain.force_delete_start.to_date + + Setting.expire_warning_period.days) + assert(@domain.purge_date.is_a?(ActiveSupport::TimeWithZone)) + assert(@domain.outzone_date.is_a?(ActiveSupport::TimeWithZone)) + end + + def test_force_delete_soft_year_ahead_sets_client_hold + asserted_status = DomainStatus::CLIENT_HOLD + + @domain.update(valid_to: Time.zone.parse('2012-08-05')) + @domain.update(template_name: 'legal_person') + assert_not @domain.force_delete_scheduled? + travel_to Time.zone.parse('2010-07-05') + @domain.schedule_force_delete(type: :soft) + + travel_to Time.zone.parse('2010-08-21') + DomainCron.start_client_hold + @domain.reload + assert_includes(@domain.statuses, asserted_status) + end + + def test_force_delete_soft_year_ahead_not_sets_client_hold_before_threshold + asserted_status = DomainStatus::CLIENT_HOLD + + @domain.update_columns(valid_to: Time.zone.parse('2010-08-05'), + force_delete_date: nil) + assert_not @domain.force_delete_scheduled? + travel_to Time.zone.parse('2010-07-05') + @domain.schedule_force_delete(type: :soft) + + travel_to Time.zone.parse('2010-07-06') + DomainCron.start_client_hold + @domain.reload + + assert_not_includes(@domain.statuses, asserted_status) + end + + def test_force_delete_fast_track_sets_client_hold + asserted_status = DomainStatus::CLIENT_HOLD + @domain.update_columns(valid_to: Time.zone.parse('2010-10-05'), + force_delete_date: nil) + + travel_to Time.zone.parse('2010-07-05') + + @domain.schedule_force_delete(type: :fast_track) + travel_to Time.zone.parse('2010-07-25') + DomainCron.start_client_hold + @domain.reload + + assert_includes(@domain.statuses, asserted_status) + end + + def test_not_sets_hold_before_treshold + asserted_status = DomainStatus::CLIENT_HOLD + @domain.update_columns(valid_to: Time.zone.parse('2010-10-05'), + force_delete_date: nil) + @domain.update(template_name: 'legal_person') + + travel_to Time.zone.parse('2010-07-05') + + @domain.schedule_force_delete(type: :fast_track) + travel_to Time.zone.parse('2010-07-06') + DomainCron.start_client_hold + @domain.reload + + assert_not_includes(@domain.statuses, asserted_status) end end diff --git a/test/models/domain/releasable/auctionable_test.rb b/test/models/domain/releasable/auctionable_test.rb index c78a148bc..de3ac0ff6 100644 --- a/test/models/domain/releasable/auctionable_test.rb +++ b/test/models/domain/releasable/auctionable_test.rb @@ -2,7 +2,7 @@ require 'test_helper' class DomainReleasableAuctionableTest < ActiveSupport::TestCase # Needed for `test_updates_whois` test because of `after_commit :update_whois_record` in Domain - self.use_transactional_fixtures = false + self.use_transactional_tests = false setup do @domain = domains(:shop) diff --git a/test/models/domain_cron_test.rb b/test/models/domain_cron_test.rb index 60cebc998..5b3b0120e 100644 --- a/test/models/domain_cron_test.rb +++ b/test/models/domain_cron_test.rb @@ -5,9 +5,14 @@ class DomainCronTest < ActiveSupport::TestCase setup do @domain = domains(:shop) + @original_expire_pending_confirmation = Setting.expire_pending_confirmation ActionMailer::Base.deliveries.clear end + teardown do + Setting.expire_pending_confirmation = @original_expire_pending_confirmation + end + def test_clean_expired_pendings_notifies_registrant_by_email Setting.expire_pending_confirmation = 0 @domain.update!(registrant_verification_asked_at: Time.zone.now, @@ -18,4 +23,33 @@ class DomainCronTest < ActiveSupport::TestCase assert_emails 1 end -end \ No newline at end of file + + def test_client_hold + Setting.redemption_grace_period = 30 + + @domain.update(valid_to: Time.zone.parse('2012-08-05')) + assert_not @domain.force_delete_scheduled? + travel_to Time.zone.parse('2010-07-05') + @domain.schedule_force_delete(type: :soft) + @domain.reload + @domain.update(template_name: 'legal_person') + travel_to Time.zone.parse('2010-08-06') + DomainCron.start_client_hold + + assert_emails 1 + end + + def test_does_not_sets_hold_if_already_set + Setting.redemption_grace_period = 30 + + @domain.update(valid_to: Time.zone.parse('2012-08-05')) + travel_to Time.zone.parse('2010-07-05') + @domain.schedule_force_delete(type: :soft) + @domain.reload + @domain.update(template_name: 'legal_person', statuses: [DomainStatus::CLIENT_HOLD]) + travel_to Time.zone.parse('2010-08-06') + DomainCron.start_client_hold + + assert_emails 0 + end +end diff --git a/test/models/domain_test.rb b/test/models/domain_test.rb index 98baa084a..ec6f60c52 100644 --- a/test/models/domain_test.rb +++ b/test/models/domain_test.rb @@ -3,25 +3,284 @@ require 'test_helper' class DomainTest < ActiveSupport::TestCase setup do @domain = domains(:shop) + + @original_nameserver_required = Setting.nameserver_required + @original_min_admin_contact_count = Setting.admin_contacts_min_count + @original_max_admin_contact_count = Setting.admin_contacts_max_count + @original_min_tech_contact_count = Setting.tech_contacts_min_count + @original_max_tech_contact_count = Setting.tech_contacts_max_count end - def test_valid_fixture_is_valid - assert @domain.valid? + teardown do + Setting.nameserver_required = @original_nameserver_required + Setting.admin_contacts_min_count = @original_min_admin_contact_count + Setting.admin_contacts_max_count = @original_max_admin_contact_count + Setting.tech_contacts_min_count = @original_min_tech_contact_count + Setting.tech_contacts_max_count = @original_max_tech_contact_count + end + + def test_valid_domain_is_valid + assert valid_domain.valid?, proc { valid_domain.errors.full_messages } end def test_invalid_fixture_is_invalid assert domains(:invalid).invalid? end + # https://www.internet.ee/domeenid/ee-domeenireeglid#domeeninimede-registreerimine + def test_validates_name_format + assert_equal dns_zones(:one).origin, 'test' + domain = valid_domain + subdomain_min_length = 1 + subdomain_max_length = 63 + + domain.name = '!invalid' + assert domain.invalid? + + domain.name = 'aa--a.test' + assert domain.invalid? + + domain.name = '-example.test' + assert domain.invalid? + + domain.name = 'example-.test' + assert domain.invalid? + + domain.name = "#{'a' * subdomain_max_length.next}.test" + assert domain.invalid? + + domain.name = 'рф.test' + assert domain.invalid? + + domain.name = "#{'a' * subdomain_min_length}.test" + assert domain.valid? + + domain.name = "#{'a' * subdomain_max_length}.test" + assert domain.valid? + + domain.name = 'example-1-2.test' + assert domain.valid? + + domain.name = 'EXAMPLE.test' + assert domain.valid? + + domain.name = 'äõöüšž.test' + assert domain.valid? + + domain.name = 'xn--mnchen-3ya.test' + assert domain.valid? + end + + def test_invalid_when_name_is_already_taken + Setting.admin_contacts_min_count = Setting.tech_contacts_min_count = 0 + another_domain = valid_domain + domain = another_domain.dup + + domain.name = another_domain.name + assert domain.invalid? + + domain.name = "new.#{dns_zones(:one).origin}" + assert domain.valid?, proc { domain.errors.full_messages } + end + + def test_invalid_when_name_is_zone + name = dns_zones(:one).origin + domain = valid_domain + + domain.name = name + + assert domain.invalid? + assert_includes domain.errors.full_messages, 'Data management policy violation:' \ + ' Domain name is blocked [name]' + end + + def test_invalid_without_transfer_code + domain = valid_domain + domain.transfer_code = '' + assert domain.invalid? + end + + def test_invalid_when_domain_is_reserved + reserved_domain = reserved_domains(:one) + domain = valid_domain.dup + domain.name = reserved_domain.name + + assert domain.invalid? + assert_includes domain.errors.full_messages, 'Required parameter missing; reserved>' \ + 'pw element required for reserved domains' + end + + def test_invalid_without_registration_period + domain = valid_domain + domain.period = '' + assert domain.invalid? + end + + def test_validates_registration_period_format + domain = valid_domain + + domain.period = 'invalid' + assert domain.invalid? + + domain.period = 1.1 + assert domain.invalid? + + domain.period = 1 + assert domain.valid? + end + + def test_invalid_when_the_same_admin_contact_is_linked_twice + domain = valid_domain + contact = contacts(:john) + + domain.admin_contacts << contact + assert_raise ActiveRecord::RecordNotUnique do + domain.admin_contacts << contact + end + end + + def test_invalid_when_the_same_tech_contact_is_linked_twice + domain = valid_domain + contact = contacts(:john) + + domain.tech_contacts << contact + assert_raise ActiveRecord::RecordNotUnique do + domain.tech_contacts << contact + end + end + + def test_validates_name_server_count_when_name_servers_are_required + nameserver_attributes = nameservers(:shop_ns1).dup.attributes + domain = valid_domain + Setting.nameserver_required = true + min_count = 1 + max_count = 2 + Setting.ns_min_count = min_count + Setting.ns_max_count = max_count + + domain.nameservers.clear + min_count.times { domain.nameservers.build(nameserver_attributes) } + assert domain.valid?, proc { domain.errors.full_messages } + + domain.nameservers.clear + max_count.times do |i| + domain.nameservers.build(nameserver_attributes.merge(hostname: "ns#{i}.test")) + end + assert domain.valid?, proc { domain.errors.full_messages } + + domain.nameservers.clear + assert domain.invalid? + + domain.nameservers.clear + max_count.next.times do |i| + domain.nameservers.build(nameserver_attributes.merge(hostname: "ns#{i}.test")) + end + assert domain.invalid? + end + + def test_valid_without_name_servers_when_they_are_optional + domain = valid_domain + domain.nameservers.clear + Setting.nameserver_required = false + Setting.ns_min_count = 1 + + assert domain.valid? + end + + def test_validates_admin_contact_count + domain_contact_attributes = domain_contacts(:shop_jane).dup.attributes + domain = valid_domain + min_count = 1 + max_count = 2 + Setting.admin_contacts_min_count = min_count + Setting.admin_contacts_max_count = max_count + + domain.admin_domain_contacts.clear + min_count.times { domain.admin_domain_contacts.build(domain_contact_attributes) } + assert domain.valid?, proc { domain.errors.full_messages } + + domain.admin_domain_contacts.clear + max_count.times { domain.admin_domain_contacts.build(domain_contact_attributes) } + assert domain.valid?, proc { domain.errors.full_messages } + + domain.admin_domain_contacts.clear + assert domain.invalid? + + domain.admin_domain_contacts.clear + max_count.next.times { domain.admin_domain_contacts.build(domain_contact_attributes) } + assert domain.invalid? + end + + def test_validates_tech_contact_count + domain_contact_attributes = domain_contacts(:shop_william).dup.attributes + domain = valid_domain + min_count = 1 + max_count = 2 + Setting.tech_contacts_min_count = min_count + Setting.tech_contacts_max_count = max_count + + domain.tech_domain_contacts.clear + min_count.times { domain.tech_domain_contacts.build(domain_contact_attributes) } + assert domain.valid?, proc { domain.errors.full_messages } + + domain.tech_domain_contacts.clear + max_count.times { domain.tech_domain_contacts.build(domain_contact_attributes) } + assert domain.valid?, proc { domain.errors.full_messages } + + domain.tech_domain_contacts.clear + assert domain.invalid? + + domain.tech_domain_contacts.clear + max_count.next.times { domain.tech_domain_contacts.build(domain_contact_attributes) } + assert domain.invalid? + end + + def test_outzone_candidates_scope_returns_records_with_outzone_at_in_the_past + travel_to Time.zone.parse('2010-07-05 08:00:00') + domain1 = domains(:shop) + domain1.update!(outzone_at: Time.zone.parse('2010-07-05 07:59:59')) + domain2 = domains(:airport) + domain2.update!(outzone_at: Time.zone.parse('2010-07-05 08:00:00')) + domain3 = domains(:library) + domain3.update!(outzone_at: Time.zone.parse('2010-07-05 08:00:01')) + Domain.connection.disable_referential_integrity do + Domain.where("id NOT IN (#{[domain1.id, domain2.id, domain3.id].join(',')})").delete_all + end + + assert_equal [domain1.id], Domain.outzone_candidates.ids + end + + def test_expired_scope_returns_records_with_valid_to_in_the_past + travel_to Time.zone.parse('2010-07-05 08:00:00') + domain1 = domains(:shop) + domain1.update!(valid_to: Time.zone.parse('2010-07-05 07:59:59')) + domain2 = domains(:airport) + domain2.update!(valid_to: Time.zone.parse('2010-07-05 08:00:00')) + domain3 = domains(:library) + domain3.update!(valid_to: Time.zone.parse('2010-07-05 08:00:01')) + Domain.connection.disable_referential_integrity do + Domain.where("id NOT IN (#{[domain1.id, domain2.id, domain3.id].join(',')})").delete_all + end + + assert_equal [domain1.id, domain2.id].sort, Domain.expired.ids.sort + end + def test_domain_name domain = Domain.new(name: 'shop.test') assert_equal 'shop.test', domain.domain_name.to_s end + def test_nil_name_doesnt_throw_error + domain = Domain.new(name: 'shop.test') + assert_nothing_raised do + domain.name = nil + end + end + def test_returns_registrant_user_domains_by_registrant registrant = contacts(:john).becomes(Registrant) assert_equal registrant, @domain.registrant - registrant_user = RegistrantUser.new + registrant_user = RegistrantUser.new(registrant_ident: 'US-12345') registrant_user.stub(:contacts, [registrant]) do assert_includes Domain.registrant_user_domains(registrant_user), @domain @@ -32,7 +291,7 @@ class DomainTest < ActiveSupport::TestCase contact = contacts(:jane) assert_not_equal contact.becomes(Registrant), @domain.registrant assert_includes @domain.contacts, contact - registrant_user = RegistrantUser.new + registrant_user = RegistrantUser.new(registrant_ident: 'US-12345') registrant_user.stub(:contacts, [contact]) do assert_includes Domain.registrant_user_domains(registrant_user), @domain @@ -79,4 +338,103 @@ class DomainTest < ActiveSupport::TestCase assert_equal %w[john@inbox.test william@inbox.test].sort, @domain.primary_contact_emails.sort end -end \ No newline at end of file + + def test_normalizes_name + unnormalized_name = ' Foo.test ' + domain = Domain.new(name: unnormalized_name) + + assert_equal 'foo.test', domain.name + assert_equal 'foo.test', domain.name_puny + assert_equal unnormalized_name, domain.name_dirty + end + + def test_converts_name_to_punycode + domain = Domain.new(name: 'münchen.test') + assert_equal 'xn--mnchen-3ya.test', domain.name_puny + end + + def test_returns_new_registrant_id + id = 1 + domain = Domain.new(pending_json: { new_registrant_id: id }) + + assert_equal id, domain.new_registrant_id + end + + def test_returns_new_registrant_email + email = 'john@inbox.test' + domain = Domain.new(pending_json: { new_registrant_email: email }) + + assert_equal email, domain.new_registrant_email + end + + def test_expiration + now = Time.zone.parse('2010-07-05 08:00:00') + travel_to now + domain = Domain.new + + domain.valid_to = now + 1.second + assert domain.registered? + assert_not domain.expired? + + domain.valid_to = now + assert domain.expired? + assert_not domain.registered? + + domain.valid_to = now - 1.second + assert domain.expired? + assert_not domain.registered? + end + + def test_activation + domain = inactive_domain + + assert domain.inactive? + assert_not domain.active? + + domain.activate + + assert domain.active? + assert_not domain.inactive? + end + + def test_deactivation + domain = @domain + + assert domain.active? + assert_not domain.inactive? + + domain.deactivate + + assert domain.inactive? + assert_not domain.active? + end + + def test_registrant_change_removes_force_delete + @domain.update_columns(valid_to: Time.zone.parse('2010-10-05'), + force_delete_date: nil) + @domain.update(template_name: 'legal_person') + travel_to Time.zone.parse('2010-07-05') + @domain.schedule_force_delete(type: :fast_track) + assert(@domain.force_delete_scheduled?) + other_registrant = Registrant.find_by(code: 'jane-001') + @domain.pending_json['new_registrant_id'] = other_registrant.id + + @domain.registrant = other_registrant + @domain.save! + + assert_not(@domain.force_delete_scheduled?) + end + + private + + def valid_domain + domains(:shop) + end + + def inactive_domain + Setting.nameserver_required = true + domain = @domain + domain.update!(statuses: [DomainStatus::INACTIVE]) + domain + end +end diff --git a/test/models/epp/response/result/code_test.rb b/test/models/epp/response/result/code_test.rb new file mode 100644 index 000000000..f16013180 --- /dev/null +++ b/test/models/epp/response/result/code_test.rb @@ -0,0 +1,92 @@ +require 'test_helper' + +class EppResponseResultCodeTest < ActiveSupport::TestCase + def test_creates_code_by_key + key = :completed_successfully + assert_includes Epp::Response::Result::Code.codes.keys, key + + assert_kind_of Epp::Response::Result::Code, Epp::Response::Result::Code.key(key) + end + + def test_creates_new_code_by_string_value + code_value = Epp::Response::Result::Code.codes.values.first + code = Epp::Response::Result::Code.new(code_value.to_s) + assert_equal code_value, code.value + end + + def test_invalid_code_value + invalid_code_value = 0000 + refute_includes Epp::Response::Result::Code.codes.values, invalid_code_value + + e = assert_raises ArgumentError do + Epp::Response::Result::Code.new(invalid_code_value) + end + assert_equal "Invalid value: #{invalid_code_value}", e.message + end + + def test_returns_code_values + codes = { + completed_successfully: 1000, + completed_successfully_action_pending: 1001, + completed_without_address: 1100, + completed_successfully_no_messages: 1300, + completed_successfully_ack_to_dequeue: 1301, + completed_successfully_ending_session: 1500, + unknown_command: 2000, + syntax_error: 2001, + use_error: 2002, + required_parameter_missing: 2003, + parameter_value_range_error: 2004, + parameter_value_syntax_error: 2005, + billing_failure: 2104, + unimplemented: 2101, + object_is_not_eligible_for_renewal: 2105, + object_is_not_eligible_for_transfer: 2106, + authorization_error: 2201, + invalid_authorization_information: 2202, + object_does_not_exist: 2303, + object_status_prohibits_operation: 2304, + object_association_prohibits_operation: 2305, + parameter_value_policy_error: 2306, + data_management_policy_violation: 2308, + command_failed: 2400, + authentication_error_server_closing_connection: 2501, + } + assert_equal codes, Epp::Response::Result::Code.codes + end + + def test_returns_default_descriptions + descriptions = { + 1000 => 'Command completed successfully', + 1001 => 'Command completed successfully; action pending', + 1100 => 'Command completed successfully; Postal address data discarded', + 1300 => 'Command completed successfully; no messages', + 1301 => 'Command completed successfully; ack to dequeue', + 1500 => 'Command completed successfully; ending session', + 2000 => 'Unknown command', + 2001 => 'Command syntax error', + 2002 => 'Command use error', + 2003 => 'Required parameter missing', + 2004 => 'Parameter value range error', + 2005 => 'Parameter value syntax error', + 2101 => 'Unimplemented command', + 2104 => 'Billing failure', + 2105 => 'Object is not eligible for renewal', + 2106 => 'Object is not eligible for transfer', + 2201 => 'Authorization error', + 2202 => 'Invalid authorization information', + 2303 => 'Object does not exist', + 2304 => 'Object status prohibits operation', + 2305 => 'Object association prohibits operation', + 2306 => 'Parameter value policy error', + 2308 => 'Data management policy violation', + 2400 => 'Command failed', + 2501 => 'Authentication error; server closing connection', + } + assert_equal descriptions, Epp::Response::Result::Code.default_descriptions + end + + def test_equality + assert_equal Epp::Response::Result::Code.new(1000), Epp::Response::Result::Code.new(1000) + end +end diff --git a/test/models/epp/response/result_test.rb b/test/models/epp/response/result_test.rb new file mode 100644 index 000000000..18947aa9a --- /dev/null +++ b/test/models/epp/response/result_test.rb @@ -0,0 +1,5 @@ +require 'test_helper' + +class EppResponseResultTest < ActiveSupport::TestCase + +end diff --git a/test/models/epp/response_test.rb b/test/models/epp/response_test.rb new file mode 100644 index 000000000..9f82bd205 --- /dev/null +++ b/test/models/epp/response_test.rb @@ -0,0 +1,29 @@ +require 'test_helper' + +class EppResponseTest < ActiveSupport::TestCase + def test_creates_new_response_from_xml_doc + xml = <<-XML + + + + + any + + + + XML + + assert_kind_of Epp::Response, Epp::Response.xml(xml) + end + + def test_code_predicate + present_code = Epp::Response::Result::Code.key(:completed_successfully) + absent_code = Epp::Response::Result::Code.key(:required_parameter_missing) + + result = Epp::Response::Result.new(code: present_code) + response = Epp::Response.new(results: [result]) + + assert response.code?(present_code) + assert_not response.code?(absent_code) + end +end diff --git a/test/models/invoice_test.rb b/test/models/invoice_test.rb index 6e6971139..9c1c45610 100644 --- a/test/models/invoice_test.rb +++ b/test/models/invoice_test.rb @@ -11,7 +11,8 @@ class InvoiceTest < ActiveSupport::TestCase def test_overdue_scope_returns_unpaid_uncancelled_invoices_with_past_due_date travel_to Time.zone.parse('2010-07-05') - @invoice.update!(account_activity: nil, cancelled_at: nil, due_date: '2010-07-04') + @invoice.update!(account_activity: nil, cancelled_at: nil, issue_date: '2010-07-04', + due_date: '2010-07-04') assert Invoice.overdue.include?(@invoice), 'Should return overdue invoice' end @@ -108,4 +109,4 @@ class InvoiceTest < ActiveSupport::TestCase seller_zip: nil) assert_equal 'street, city, state', invoice.seller_address end -end \ No newline at end of file +end diff --git a/test/models/nameserver/glue_record_test.rb b/test/models/nameserver/glue_record_test.rb index 599f04ec6..cec33ebf6 100644 --- a/test/models/nameserver/glue_record_test.rb +++ b/test/models/nameserver/glue_record_test.rb @@ -5,23 +5,42 @@ class NameserverGlueRecordTest < ActiveSupport::TestCase @nameserver = nameservers(:shop_ns1) end - def test_invalid_without_ip_if_glue_record_is_required - @nameserver.hostname = 'ns1.shop.test' - @nameserver.ipv4 = @nameserver.ipv6 = '' - assert @nameserver.invalid? - assert_includes @nameserver.errors.full_messages, 'Either IPv4 or IPv6 is required' \ + def test_invalid_when_glue_record_is_required_and_no_ip_is_provided + domain = Domain.new(name: 'shop.test') + nameserver = Nameserver.new(domain: domain, hostname: 'ns1.shop.test') + + assert nameserver.invalid? + assert_includes nameserver.errors.full_messages, 'Either IPv4 or IPv6 is required' \ ' for glue record generation' end - def test_valid_with_ip_if_glue_record_is_required - @nameserver.hostname = 'ns1.shop.test' - @nameserver.ipv4 = ['192.0.2.1'] - @nameserver.ipv6 = '' - assert @nameserver.valid? + def test_valid_when_glue_record_is_required_and_ipv4_is_provided + domain = Domain.new(name: 'shop.test') + nameserver = Nameserver.new(domain: domain, hostname: 'ns1.shop.test') + nameserver.ipv4 = ['192.0.2.1'] + + assert nameserver.valid? end - def test_valid_without_ip_if_glue_record_is_not_required - @nameserver.ipv4 = @nameserver.ipv6 = '' - assert @nameserver.valid? + def test_valid_when_glue_record_is_required_and_ipv6_is_provided + domain = Domain.new(name: 'shop.test') + nameserver = Nameserver.new(domain: domain, hostname: 'ns1.shop.test') + nameserver.ipv6 = ['2001:db8::1'] + + assert nameserver.valid? + end + + def test_valid_when_glue_record_is_not_required_and_no_ip_is_provided + domain = Domain.new(name: 'shop.test') + nameserver = Nameserver.new(domain: domain, hostname: 'ns1.registrar.test') + + assert nameserver.valid? + end + + def test_valid_when_glue_record_is_not_required_and_no_ip_is_provided_substring_match + domain = Domain.new(name: 'le.test') + nameserver = Nameserver.new(domain: domain, hostname: 'ns1.shop.test') + + assert nameserver.valid? end end diff --git a/test/models/payment_orders/bank_link_test.rb b/test/models/payment_orders/bank_link_test.rb index f1069819c..30d91cb7c 100644 --- a/test/models/payment_orders/bank_link_test.rb +++ b/test/models/payment_orders/bank_link_test.rb @@ -8,7 +8,7 @@ class BankLinkTest < ActiveSupport::TestCase super @invoice = invoices(:one) - @invoice.update!(total: 12) + @invoice.update!(account_activity: nil, total: 12) travel_to '2018-04-01 00:30 +0300' create_new_bank_link @@ -36,11 +36,11 @@ class BankLinkTest < ActiveSupport::TestCase 'VK_MAC': 'CZZvcptkxfuOxRR88JmT4N+Lw6Hs4xiQfhBWzVYldAcRTQbcB/lPf9MbJzBE4e1/HuslQgkdCFt5g1xW2lJwrVDBQTtP6DAHfvxU3kkw7dbk0IcwhI4whUl68/QCwlXEQTAVDv1AFnGVxXZ40vbm/aLKafBYgrirB5SUe8+g9FE=', 'VK_ENCODING': 'UTF-8', 'VK_LANG': 'ENG' - }.with_indifferent_access + }.as_json - @completed_bank_link = PaymentOrders::BankLink.new( - 'seb', @invoice, { response: params } - ) + @completed_bank_link = PaymentOrder.new(type: 'PaymentOrders::Seb', + invoice: @invoice, + response: params) end def create_cancelled_bank_link @@ -55,16 +55,17 @@ class BankLinkTest < ActiveSupport::TestCase 'VK_MAC': 'PElE2mYXXN50q2UBvTuYU1rN0BmOQcbafPummDnWfNdm9qbaGQkGyOn0XaaFGlrdEcldXaHBbZKUS0HegIgjdDfl2NOk+wkLNNH0Iu38KzZaxHoW9ga7vqiyKHC8dcxkHiO9HsOnz77Sy/KpWCq6cz48bi3fcMgo+MUzBMauWoQ=', 'VK_ENCODING': 'UTF-8', 'VK_LANG': 'ENG' - }.with_indifferent_access + }.as_json - @cancelled_bank_link = PaymentOrders::BankLink.new( - 'seb', @invoice, { response: params } - ) + @cancelled_bank_link = PaymentOrder.new(type: 'PaymentOrders::Seb', + invoice: @invoice, + response: params) end def create_new_bank_link - params = { return_url: 'return.url', response_url: 'response.url' } - @new_bank_link = PaymentOrders::BankLink.new('seb', @invoice, params) + @new_bank_link = PaymentOrder.new(type: 'PaymentOrders::Seb', invoice: @invoice) + @new_bank_link.return_url = 'return.url' + @new_bank_link.response_url = 'response.url' end def test_response_is_not_valid_when_it_is_missing @@ -105,21 +106,14 @@ class BankLinkTest < ActiveSupport::TestCase refute(@cancelled_bank_link.settled_payment?) end - def test_complete_transaction_calls_methods_on_transaction - mock_transaction = MiniTest::Mock.new - mock_transaction.expect(:sum= , '12.00', ['12.00']) - mock_transaction.expect(:bank_reference= , '1', ['1']) - mock_transaction.expect(:buyer_bank_code= , 'testvpos', ['testvpos']) - mock_transaction.expect(:buyer_iban= , '1234', ['1234']) - mock_transaction.expect(:paid_at= , Date.parse('2018-04-01 00:30:00 +0300'), [Time.parse('2018-04-01T00:30:00+0300')]) - mock_transaction.expect(:buyer_name=, 'John Doe', ['John Doe']) - mock_transaction.expect(:save!, true) - mock_transaction.expect(:autobind_invoice, AccountActivity.new) + def test_successful_payment_creates_bank_transaction + @completed_bank_link.complete_transaction - BankTransaction.stub(:find_by, mock_transaction) do - @completed_bank_link.complete_transaction - end + transaction = BankTransaction.find_by( + sum: @completed_bank_link.response['VK_AMOUNT'], + buyer_name: @completed_bank_link.response['VK_SND_NAME'] + ) - mock_transaction.verify + assert transaction.present? end end diff --git a/test/models/payment_orders/every_pay_test.rb b/test/models/payment_orders/every_pay_test.rb index 202efc1b7..1e560f32a 100644 --- a/test/models/payment_orders/every_pay_test.rb +++ b/test/models/payment_orders/every_pay_test.rb @@ -4,36 +4,38 @@ class EveryPayTest < ActiveSupport::TestCase def setup super - @invoice = invoices(:one) + @invoice = invoices(:unpaid) @invoice.update!(total: 12) - params = { - response: - { - utf8: '✓', - _method: 'put', - authenticity_token: 'OnA69vbccQtMt3C9wxEWigs5Gpf/7z+NoxRCMkFPlTvaATs8+OgMKF1I4B2f+vuK37zCgpWZaWWtyuslRRSwkw==', - nonce: '392f2d7748bc8cb0d14f263ebb7b8932', - timestamp: '1524136727', - api_username: 'ca8d6336dd750ddb', - transaction_result: 'completed', - payment_reference: 'fd5d27b59a1eb597393cd5ff77386d6cab81ae05067e18d530b10f3802e30b56', - payment_state: 'settled', - amount: '12.00', - order_reference: 'e468a2d59a731ccc546f2165c3b1a6', - account_id: 'EUR3D1', - cc_type: 'master_card', - cc_last_four_digits: '0487', - cc_month: '10', - cc_year: '2018', - cc_holder_name: 'John Doe', - hmac_fields: 'account_id,amount,api_username,cc_holder_name,cc_last_four_digits,cc_month,cc_type,cc_year,hmac_fields,nonce,order_reference,payment_reference,payment_state,timestamp,transaction_result', - hmac: 'efac1c732835668cd86023a7abc140506c692f0d', - invoice_id: '1', - }, - } - @every_pay = PaymentOrders::EveryPay.new('every_pay', @invoice, params) - @other_pay = PaymentOrders::EveryPay.new('every_pay', @invoice, {}) + response = { + "utf8": '✓', + "_method": 'put', + "authenticity_token": 'OnA69vbccQtMt3C9wxEWigs5Gpf/7z+NoxRCMkFPlTvaATs8+OgMKF1I4B2f+vuK37zCgpWZaWWtyuslRRSwkw=="', + "nonce": '392f2d7748bc8cb0d14f263ebb7b8932', + "timestamp": '1524136727', + "api_username": 'ca8d6336dd750ddb', + "transaction_result": 'completed', + "payment_reference": 'fd5d27b59a1eb597393cd5ff77386d6cab81ae05067e18d530b10f3802e30b56', + "payment_state": 'settled', + "amount": '12.00', + "order_reference": 'e468a2d59a731ccc546f2165c3b1a6', + "account_id": 'EUR3D1', + "cc_type": 'master_card', + "cc_last_four_digits": '0487', + "cc_month": '10', + "cc_year": '2018', + "cc_holder_name": 'John Doe', + "hmac_fields": 'account_id,amount,api_username,cc_holder_name,cc_last_four_digits,cc_month,cc_type,cc_year,hmac_fields,nonce,order_reference,payment_reference,payment_state,timestamp,transaction_result', + "hmac": 'efac1c732835668cd86023a7abc140506c692f0d', + "invoice_id": '2' + }.as_json + + @successful_payment = PaymentOrder.new(type: 'PaymentOrders::EveryPay', + invoice: @invoice, + response: response) + + @failed_payment = @successful_payment.dup + @failed_payment.response['payment_state'] = 'cancelled' travel_to Time.zone.parse('2018-04-01 00:30:00 +0000') end @@ -47,37 +49,37 @@ class EveryPayTest < ActiveSupport::TestCase transaction_type: 'charge', hmac_fields: 'account_id,amount,api_username,callback_url,customer_url,hmac_fields,nonce,order_reference,timestamp,transaction_type' } - form_fields = @every_pay.form_fields + form_fields = @successful_payment.form_fields expected_fields.each do |k, v| assert_equal(v, form_fields[k]) end end def test_valid_response_from_intermediary? - assert(@every_pay.valid_response_from_intermediary?) - refute(@other_pay.valid_response_from_intermediary?) + assert(@successful_payment.valid_response_from_intermediary?) + + @failed_payment.response = { 'what': 'definitely not valid everypay response' } + refute(@failed_payment.valid_response_from_intermediary?) + end + + def test_valid_and_successful_payment_is_determined + assert(@successful_payment.payment_received?) + refute(@failed_payment.payment_received?) end def test_settled_payment? - assert(@every_pay.settled_payment?) - other_pay = PaymentOrders::EveryPay.new( - 'every_pay', @invoice, {response: {payment_state: 'CANCELLED'}} - ) - refute(other_pay.settled_payment?) + assert(@successful_payment.settled_payment?) + refute(@failed_payment.settled_payment?) end - def test_complete_transaction_calls_methods_on_transaction - mock_transaction = MiniTest::Mock.new - mock_transaction.expect(:sum= , '12.00', ['12.00']) - mock_transaction.expect(:paid_at= , Date.strptime('1524136727', '%s'), [Date.strptime('1524136727', '%s')]) - mock_transaction.expect(:buyer_name=, 'John Doe', ['John Doe']) - mock_transaction.expect(:save!, true) - mock_transaction.expect(:autobind_invoice, AccountActivity.new) + def test_successful_payment_creates_bank_transaction + @successful_payment.complete_transaction - BankTransaction.stub(:find_by, mock_transaction) do - @every_pay.complete_transaction - end + transaction = BankTransaction.find_by( + sum: @successful_payment.response['amount'], + buyer_name: @successful_payment.response['cc_holder_name'] + ) - mock_transaction.verify + assert transaction.present? end end diff --git a/test/models/payment_orders_test.rb b/test/models/payment_orders_test.rb index 252ba0582..43996c6bc 100644 --- a/test/models/payment_orders_test.rb +++ b/test/models/payment_orders_test.rb @@ -5,23 +5,21 @@ class PaymentOrdersTest < ActiveSupport::TestCase super @original_methods = ENV['payment_methods'] - @original_seb_URL = ENV['seb_payment_url'] - ENV['payment_methods'] = 'seb, swed, credit_card' + @original_seb_url = ENV['seb_payment_url'] + ENV['payment_methods'] = 'seb, swed, every_pay' ENV['seb_payment_url'] = nil - @not_implemented_payment = PaymentOrders::Base.new( - 'not_implemented', Invoice.new - ) + @not_implemented_payment = PaymentOrder.new(invoice: Invoice.new) end def teardown super ENV['payment_methods'] = @original_methods - ENV['seb_payment_url'] = @original_seb_URL + ENV['seb_payment_url'] = @original_seb_url end def test_variable_assignment - assert_equal 'not_implemented', @not_implemented_payment.type + assert_nil @not_implemented_payment.type assert_nil @not_implemented_payment.response_url assert_nil @not_implemented_payment.return_url assert_nil @not_implemented_payment.form_url @@ -45,14 +43,61 @@ class PaymentOrdersTest < ActiveSupport::TestCase end end - def test_that_create_with_type_raises_argument_error - assert_raise ArgumentError do - PaymentOrders.create_with_type("not_implemented", Invoice.new) + def test_correct_channel_is_assigned + everypay_channel = PaymentOrder.new_with_type(type: 'every_pay', invoice: @invoice) + assert_equal everypay_channel.channel, 'EveryPay' + assert_equal everypay_channel.class.config_namespace_name, 'every_pay' + + swed_channel = PaymentOrder.new_with_type(type: 'swed', invoice: @invoice) + assert_equal swed_channel.channel, 'Swed' + assert_equal swed_channel.class.config_namespace_name, 'swed' + + seb_channel = PaymentOrder.new_with_type(type: 'seb', invoice: @invoice) + assert_equal seb_channel.channel, 'Seb' + assert_equal seb_channel.class.config_namespace_name, 'seb' + + lhv_channel = PaymentOrder.new_with_type(type: 'lhv', invoice: @invoice) + assert_equal lhv_channel.channel, 'Lhv' + assert_equal lhv_channel.class.config_namespace_name, 'lhv' + + admin_channel = PaymentOrder.new_with_type(type: 'admin_payment', invoice: @invoice) + assert_equal admin_channel.channel, 'AdminPayment' + assert_equal admin_channel.class.config_namespace_name, 'admin_payment' + + system_channel = PaymentOrder.new_with_type(type: 'system_payment', invoice: @invoice) + assert_equal system_channel.channel, 'SystemPayment' + assert_equal system_channel.class.config_namespace_name, 'system_payment' + end + + def test_can_not_create_order_for_paid_invoice + invoice = invoices(:one) + payment_order = PaymentOrder.new_with_type(type: 'every_pay', invoice: invoice) + assert payment_order.invalid? + assert_includes payment_order.errors[:invoice], 'is already paid' + end + + def test_order_without_channel_is_invalid + payment_order = PaymentOrder.new + assert payment_order.invalid? + assert_includes payment_order.errors[:type], 'is not supported' + end + + def test_can_not_create_order_with_invalid_type + assert_raise NameError do + PaymentOrder.new_with_type(type: 'not_implemented', invoice: Invoice.new) end end - def test_create_with_correct_subclass - payment = PaymentOrders.create_with_type('seb', Invoice.new) - assert_equal PaymentOrders::BankLink, payment.class + def test_supported_method_bool_does_not_fail + assert_not PaymentOrder.supported_method?('not_implemented', shortname: true) + assert PaymentOrder.supported_method?('every_pay', shortname: true) + + assert_not PaymentOrder.supported_method?('PaymentOrders::NonExistant') + assert PaymentOrder.supported_method?('PaymentOrders::EveryPay') + end + + def test_can_create_with_correct_subclass + payment = PaymentOrder.new_with_type(type: 'seb', invoice: Invoice.new) + assert_equal PaymentOrders::Seb, payment.class end end diff --git a/test/models/registrant_verification_test.rb b/test/models/registrant_verification_test.rb new file mode 100644 index 000000000..ef4038784 --- /dev/null +++ b/test/models/registrant_verification_test.rb @@ -0,0 +1,33 @@ +require 'test_helper' + +class RegistrantVerificationTest < ActiveSupport::TestCase + + setup do + @domain = domains(:shop) + @initiator = users(:api_bestnames).username + @token = 'zzzzz' + @domain.update(statuses: [DomainStatus::PENDING_UPDATE], + registrant_verification_asked_at: Time.zone.now - 1.day, + registrant_verification_token: @token) + end + + def test_audit_log + registrant_verification = registrant_verifications(:one) + random_action = "random#{rand(100)}" + + assert_difference -> { RegistrantVerificationVersion.count } do + registrant_verification.update_attributes!(action: random_action) + end + end + + def test_reject_changes + @registrant_verification = RegistrantVerification.new(domain_id: @domain.id, + verification_token: @token) + start_versions_count = RegistrantVerificationVersion.count + + assert_nothing_raised do + @registrant_verification.domain_registrant_change_reject!("email link, #{@initiator}") + end + assert_equal RegistrantVerificationVersion.count, start_versions_count + 1 + end +end diff --git a/test/models/registrar_test.rb b/test/models/registrar_test.rb index 53967cfcc..091b8e6f4 100644 --- a/test/models/registrar_test.rb +++ b/test/models/registrar_test.rb @@ -3,6 +3,15 @@ require 'test_helper' class RegistrarTest < ActiveSupport::TestCase setup do @registrar = registrars(:bestnames) + @original_default_language = Setting.default_language + @original_days_to_keep_invoices_active = Setting.days_to_keep_invoices_active + @old_validation_type = Truemail.configure.default_validation_type + end + + teardown do + Setting.default_language = @original_default_language + Setting.days_to_keep_invoices_active = @original_days_to_keep_invoices_active + Truemail.configure.default_validation_type = @old_validation_type end def test_valid_registrar_is_valid @@ -31,12 +40,123 @@ class RegistrarTest < ActiveSupport::TestCase assert registrar.invalid? end + def test_email_verification_valid + registrar = valid_registrar + registrar.email = 'info@internet.ee' + registrar.billing_email = nil + + assert registrar.valid? + end + + def test_email_verification_smtp_error + Truemail.configure.default_validation_type = :smtp + + registrar = valid_registrar + registrar.email = 'somecrude1337joke@internet.ee' + registrar.billing_email = nil + + assert registrar.invalid? + assert_equal I18n.t('activerecord.errors.models.contact.attributes.email.email_smtp_check_error'), registrar.errors.messages[:email].first + end + + def test_email_verification_mx_error + Truemail.configure.default_validation_type = :mx + + registrar = valid_registrar + registrar.email = 'somecrude31337joke@somestrange31337domain.ee' + registrar.billing_email = nil + + assert registrar.invalid? + assert_equal I18n.t('activerecord.errors.models.contact.attributes.email.email_mx_check_error'), registrar.errors.messages[:email].first + end + + def test_email_verification_regex_error + Truemail.configure.default_validation_type = :regex + + registrar = valid_registrar + registrar.email = 'some@strangesentence@internet.ee' + registrar.billing_email = nil + + assert registrar.invalid? + assert_equal I18n.t('activerecord.errors.models.contact.attributes.email.email_regex_check_error'), registrar.errors.messages[:email].first + end + + def test_billing_email_verification_valid + registrar = valid_registrar + registrar.billing_email = 'info@internet.ee' + + assert registrar.valid? + end + + def test_billing_email_verification_smtp_error + Truemail.configure.default_validation_type = :smtp + + registrar = valid_registrar + registrar.billing_email = 'somecrude1337joke@internet.ee' + + assert registrar.invalid? + assert_equal I18n.t('activerecord.errors.models.contact.attributes.email.email_smtp_check_error'), registrar.errors.messages[:billing_email].first + end + + def test_billing_email_verification_mx_error + Truemail.configure.default_validation_type = :mx + + registrar = valid_registrar + registrar.billing_email = 'somecrude31337joke@somestrange31337domain.ee' + + assert registrar.invalid? + assert_equal I18n.t('activerecord.errors.models.contact.attributes.email.email_mx_check_error'), registrar.errors.messages[:billing_email].first + end + + def test_billing_email_verification_regex_error + Truemail.configure.default_validation_type = :regex + + registrar = valid_registrar + registrar.billing_email = 'some@strangesentence@internet.ee' + + assert registrar.invalid? + assert_equal I18n.t('activerecord.errors.models.contact.attributes.email.email_regex_check_error'), registrar.errors.messages[:billing_email].first + end + + def test_creates_email_verification_in_unicode + unicode_email = 'suur@äri.ee' + punycode_email = Registrar.unicode_to_punycode(unicode_email) + unicode_billing_email = 'billing@äri.ee' + punycode_billing_email = Registrar.unicode_to_punycode(unicode_billing_email) + + registrar = valid_registrar + registrar.email = punycode_email + registrar.billing_email = punycode_billing_email + registrar.save + + assert_equal registrar.email_verification.email, unicode_email + assert_equal registrar.billing_email_verification.email, unicode_billing_email + end + def test_invalid_without_accounting_customer_code registrar = valid_registrar registrar.accounting_customer_code = '' assert registrar.invalid? end + def test_optional_billing_email + registrar = valid_registrar + registrar.billing_email = '' + assert registrar.valid? + end + + def test_returns_billing_email_when_provided + billing_email = 'billing@registrar.test' + registrar = Registrar.new(billing_email: billing_email) + assert_equal billing_email, registrar.billing_email + end + + def test_billing_email_fallback + contact_email = 'info@registrar.test' + registrar = Registrar.new(contact_email: contact_email, billing_email: '') + assert_equal contact_email, registrar.billing_email + end + def test_invalid_without_language registrar = valid_registrar registrar.language = '' @@ -82,15 +202,12 @@ class RegistrarTest < ActiveSupport::TestCase def test_issues_new_invoice travel_to Time.zone.parse('2010-07-05') - @original_days_to_keep_invoices_active_setting = Setting.days_to_keep_invoices_active Setting.days_to_keep_invoices_active = 10 invoice = @registrar.issue_prepayment_invoice(100) assert_equal Date.parse('2010-07-05'), invoice.issue_date assert_equal Date.parse('2010-07-15'), invoice.due_date - - Setting.days_to_keep_invoices_active = @original_days_to_keep_invoices_active_setting end def test_issues_e_invoice_along_with_invoice @@ -119,6 +236,12 @@ class RegistrarTest < ActiveSupport::TestCase assert registrar.invalid? end + def test_aliases_contact_email_to_email + email = 'info@registrar.test' + registrar = Registrar.new(email: email) + assert_equal email, registrar.contact_email + end + def test_full_address registrar = Registrar.new(address_street: 'Main Street 1', address_zip: '1234', address_city: 'NY', address_state: 'NY State') @@ -190,6 +313,33 @@ class RegistrarTest < ActiveSupport::TestCase assert_equal iban, registrar.e_invoice_iban end + def test_legal_doc_is_mandatory + old_value = Setting.legal_document_is_mandatory + Setting.legal_document_is_mandatory = true + assert @registrar.legaldoc_mandatory? + + Setting.legal_document_is_mandatory = old_value + end + + def test_legal_doc_is_not_mandatory_if_opted_out + old_value = Setting.legal_document_is_mandatory + Setting.legal_document_is_mandatory = true + @registrar.legaldoc_optout = true + @registrar.save(validate: false) + @registrar.reload + assert_not @registrar.legaldoc_mandatory? + + Setting.legal_document_is_mandatory = old_value + end + + def test_legal_doc_is_not_mandatory_globally + old_value = Setting.legal_document_is_mandatory + Setting.legal_document_is_mandatory = false + assert_not @registrar.legaldoc_mandatory? + + Setting.legal_document_is_mandatory = old_value + end + private def valid_registrar @@ -209,4 +359,4 @@ class RegistrarTest < ActiveSupport::TestCase Registry.current.vat_country = Country.new(:us) registrar end -end \ No newline at end of file +end diff --git a/test/models/registry_test.rb b/test/models/registry_test.rb index 5ec10ec9e..1fe6e9ef2 100644 --- a/test/models/registry_test.rb +++ b/test/models/registry_test.rb @@ -1,6 +1,16 @@ require 'test_helper' class RegistryTest < ActiveSupport::TestCase + setup do + @original_registry_vat_rate = Setting.registry_vat_prc + @original_registry_country_code = Setting.registry_country_code + end + + teardown do + Setting.registry_vat_prc = @original_registry_vat_rate + Setting.registry_country_code = @original_registry_country_code + end + def test_returns_current_registry Setting.registry_vat_prc = 0.2 Setting.registry_country_code = 'US' diff --git a/test/models/setting_entry_test.rb b/test/models/setting_entry_test.rb new file mode 100644 index 000000000..ff9791fc6 --- /dev/null +++ b/test/models/setting_entry_test.rb @@ -0,0 +1,120 @@ +require 'test_helper' + +class SettingEntryTest < ActiveSupport::TestCase + def setup + @new_setting = SettingEntry.new(code: 'new_setting', value: 'looks great', format: 'string', group: 'other') + end + + def test_fixture_is_valid + assert setting_entries(:legal_document_is_mandatory).valid? + end + + def test_can_be_retrieved_via_class_method + setting = setting_entries(:legal_document_is_mandatory) + assert setting.retrieve, Setting.legal_document_is_mandatory + end + + def test_can_be_updated_via_class_method + setting = setting_entries(:legal_document_is_mandatory) + setting.update(value: 'false') + setting.reload + + Setting.legal_document_is_mandatory = true + setting.reload + assert true, setting.retrieve + end + + def test_setting_code_is_required + assert @new_setting.valid? + @new_setting.code = nil + assert_not @new_setting.valid? + end + + def test_setting_code_can_only_include_underscore_and_characters + assert @new_setting.valid? + @new_setting.code = 'a b' + assert_not @new_setting.valid? + + @new_setting.code = 'ab_' + assert_not @new_setting.valid? + + @new_setting.code = '_ab' + assert_not @new_setting.valid? + + @new_setting.code = '1_2' + assert_not @new_setting.valid? + + @new_setting.code = 'a_b' + assert @new_setting.valid? + end + + def test_setting_value_can_be_nil + assert @new_setting.valid? + @new_setting.value = nil + assert @new_setting.valid? + end + + def test_setting_format_is_required + assert @new_setting.valid? + @new_setting.format = nil + assert_not @new_setting.valid? + + @new_setting.format = 'nonexistant' + assert_not @new_setting.valid? + end + + def test_setting_group_is_required + assert @new_setting.valid? + @new_setting.group = nil + assert_not @new_setting.valid? + + @new_setting.group = 'random' + assert @new_setting.valid? + end + + def test_returns_nil_for_unknown_setting + assert_nil Setting.unknown_and_definitely_not_saved_setting + end + + def test_throws_error_if_updating_unknown_setting + assert_raises ActiveRecord::RecordNotFound do + Setting.unknown_and_definitely_not_saved_setting = 'hope it fails' + end + end + + def test_parses_string_format + Setting.create(code: 'string_format', value: '1', format: 'string', group: 'random') + assert Setting.string_format.is_a? String + end + + def test_parses_integer_format + Setting.create(code: 'integer_format', value: '1', format: 'integer', group: 'random') + assert Setting.integer_format.is_a? Integer + end + + def test_parses_float_format + Setting.create(code: 'float_format', value: '0.5', format: 'float', group: 'random') + assert Setting.float_format.is_a? Float + end + + def test_parses_boolean_format + Setting.create(code: 'boolean_format', value: 'true', format: 'boolean', group: 'random') + assert_equal true, Setting.boolean_format + + Setting.boolean_format = 'false' + assert_equal false, Setting.boolean_format + + Setting.boolean_format = nil + assert_equal false, Setting.boolean_format + end + + def test_parses_hash_format + Setting.create(code: 'hash_format', value: '{"hello": "there"}', format: 'hash', group: 'random') + assert Setting.hash_format.is_a? Hash + end + + def test_parses_array_format + Setting.create(code: 'array_format', value: '[1, 2, 3]', format: 'array', group: 'random') + assert Setting.array_format.is_a? Array + end +end diff --git a/test/models/white_ip_test.rb b/test/models/white_ip_test.rb new file mode 100644 index 000000000..607887730 --- /dev/null +++ b/test/models/white_ip_test.rb @@ -0,0 +1,54 @@ +require 'test_helper' + +class WhiteIpTest < ActiveSupport::TestCase + def test_either_ipv4_or_ipv6_is_required + white_ip = valid_white_ip + + white_ip.ipv4 = '' + white_ip.ipv6 = '' + assert white_ip.invalid? + assert_includes white_ip.errors.full_messages, 'IPv4 or IPv6 must be present' + + white_ip.ipv4 = valid_ipv4 + white_ip.ipv6 = '' + assert white_ip.valid? + + white_ip.ipv4 = '' + white_ip.ipv6 = valid_ipv6 + assert white_ip.valid? + end + + def test_validates_ipv4_format + white_ip = valid_white_ip + + white_ip.ipv4 = 'invalid' + assert white_ip.invalid? + + white_ip.ipv4 = valid_ipv4 + assert white_ip.valid? + end + + def test_validates_ipv6_format + white_ip = valid_white_ip + + white_ip.ipv6 = 'invalid' + assert white_ip.invalid? + + white_ip.ipv6 = valid_ipv6 + assert white_ip.valid? + end + + private + + def valid_white_ip + white_ips(:one) + end + + def valid_ipv4 + '192.0.2.1' + end + + def valid_ipv6 + '2001:db8::1' + end +end diff --git a/test/models/whois/record_test.rb b/test/models/whois/record_test.rb index 43707b186..3e727d80a 100644 --- a/test/models/whois/record_test.rb +++ b/test/models/whois/record_test.rb @@ -7,12 +7,12 @@ class Whois::RecordTest < ActiveSupport::TestCase @whois_record = whois_records(:one) @auction = auctions(:one) - @original_disclaimer_setting = Setting.registry_whois_disclaimer + @original_disclaimer = Setting.registry_whois_disclaimer Setting.registry_whois_disclaimer = 'disclaimer' end teardown do - Setting.registry_whois_disclaimer = @original_disclaimer_setting + Setting.registry_whois_disclaimer = @original_disclaimer end def test_reads_disclaimer_setting @@ -40,24 +40,36 @@ class Whois::RecordTest < ActiveSupport::TestCase end def test_updates_whois_record_from_auction_when_awaiting_payment - @auction.update!(domain: 'domain.test', status: Auction.statuses[:awaiting_payment]) + @auction.update!(domain: 'domain.test', + status: Auction.statuses[:awaiting_payment], + registration_deadline: registration_deadline) @whois_record.update!(name: 'domain.test') @whois_record.update_from_auction(@auction) @whois_record.reload assert_equal ({ 'name' => 'domain.test', 'status' => ['PendingRegistration'], - 'disclaimer' => 'disclaimer' }), @whois_record.json + 'disclaimer' => 'disclaimer', + 'registration_deadline' => registration_deadline.try(:to_s, :iso8601) }), + @whois_record.json end def test_updates_whois_record_from_auction_when_payment_received - @auction.update!(domain: 'domain.test', status: Auction.statuses[:payment_received]) + @auction.update!(domain: 'domain.test', + status: Auction.statuses[:payment_received], + registration_deadline: registration_deadline) @whois_record.update!(name: 'domain.test') @whois_record.update_from_auction(@auction) @whois_record.reload assert_equal ({ 'name' => 'domain.test', 'status' => ['PendingRegistration'], - 'disclaimer' => 'disclaimer' }), @whois_record.json + 'disclaimer' => 'disclaimer', + 'registration_deadline' => registration_deadline.try(:to_s, :iso8601) }), + @whois_record.json end -end \ No newline at end of file + + def registration_deadline + Time.zone.now + 10.days + end +end diff --git a/test/services/overdue_invoice_canceller_test.rb b/test/services/overdue_invoice_canceller_test.rb index 6dd2ea3b4..bc3447484 100644 --- a/test/services/overdue_invoice_canceller_test.rb +++ b/test/services/overdue_invoice_canceller_test.rb @@ -2,7 +2,11 @@ require 'test_helper' class OverdueInvoiceCancellerTest < ActiveSupport::TestCase setup do - @invoice = invoices(:one) + @original_days_to_keep_overdue_invoices_active = Setting.days_to_keep_overdue_invoices_active + end + + teardown do + Setting.days_to_keep_overdue_invoices_active = @original_days_to_keep_overdue_invoices_active end def test_default_delay @@ -23,26 +27,24 @@ class OverdueInvoiceCancellerTest < ActiveSupport::TestCase def test_cancels_overdue_invoices travel_to Time.zone.parse('2010-07-05') - @invoice.update!(account_activity: nil, cancelled_at: nil, due_date: '2010-07-03') - assert @invoice.cancellable? + invoice = cancellable_invoice(due_date: '2010-07-03') canceller = OverdueInvoiceCanceller.new(delay: 1.day) canceller.cancel - @invoice.reload + invoice.reload - assert @invoice.cancelled? + assert invoice.cancelled? end def test_yields_cancelled_invoices travel_to Time.zone.parse('2010-07-05') - @invoice.update!(account_activity: nil, cancelled_at: nil, due_date: '2010-07-03') - assert @invoice.cancellable? + invoice = cancellable_invoice(due_date: '2010-07-03') canceller = OverdueInvoiceCanceller.new(delay: 1.day) iteration_count = 0 - canceller.cancel do |invoice| - assert_equal @invoice, invoice + canceller.cancel do |cancelled_invoice| + assert_equal invoice, cancelled_invoice iteration_count += 1 end assert_equal 1, iteration_count @@ -50,13 +52,21 @@ class OverdueInvoiceCancellerTest < ActiveSupport::TestCase def test_keeps_not_overdue_invoices_intact travel_to Time.zone.parse('2010-07-05') - @invoice.update!(account_activity: nil, cancelled_at: nil, due_date: '2010-07-04') - assert @invoice.cancellable? + invoice = cancellable_invoice(due_date: '2010-07-04') canceller = OverdueInvoiceCanceller.new(delay: 1.day) canceller.cancel - @invoice.reload + invoice.reload - assert @invoice.not_cancelled? + assert invoice.not_cancelled? end -end \ No newline at end of file + + private + + def cancellable_invoice(due_date:) + invoice = invoices(:one) + invoice.update!(account_activity: nil, cancelled_at: nil, issue_date: due_date, + due_date: due_date) + invoice + end +end diff --git a/test/support/assertions/epp_assertions.rb b/test/support/assertions/epp_assertions.rb new file mode 100644 index 000000000..3f955a7e0 --- /dev/null +++ b/test/support/assertions/epp_assertions.rb @@ -0,0 +1,14 @@ +module Assertions + module EppAssertions + def assert_epp_response(code_key, message = nil) + assert epp_response.code?(Epp::Response::Result::Code.key(code_key)), message + end + + private + + def epp_response + @epp_response = Epp::Response.xml(response.body) unless @epp_response + @epp_response + end + end +end diff --git a/test/support/rails5_assertions.rb b/test/support/rails5_assertions.rb deleted file mode 100644 index 55a2e8dc6..000000000 --- a/test/support/rails5_assertions.rb +++ /dev/null @@ -1,94 +0,0 @@ -module ActiveSupport - module Testing - module Assertions - UNTRACKED = Object.new # :nodoc: - - # Assertion that the result of evaluating an expression is changed before - # and after invoking the passed in block. - # - # assert_changes 'Status.all_good?' do - # post :create, params: { status: { ok: false } } - # end - # - # You can pass the block as a string to be evaluated in the context of - # the block. A lambda can be passed for the block as well. - # - # assert_changes -> { Status.all_good? } do - # post :create, params: { status: { ok: false } } - # end - # - # The assertion is useful to test side effects. The passed block can be - # anything that can be converted to string with #to_s. - # - # assert_changes :@object do - # @object = 42 - # end - # - # The keyword arguments :from and :to can be given to specify the - # expected initial value and the expected value after the block was - # executed. - # - # assert_changes :@object, from: nil, to: :foo do - # @object = :foo - # end - # - # An error message can be specified. - # - # assert_changes -> { Status.all_good? }, 'Expected the status to be bad' do - # post :create, params: { status: { incident: true } } - # end - def assert_changes(expression, message = nil, from: UNTRACKED, to: UNTRACKED, &block) - exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) } - - before = exp.call - retval = yield - - unless from == UNTRACKED - error = "#{expression.inspect} isn't #{from.inspect}" - error = "#{message}.\n#{error}" if message - assert from === before, error - end - - after = exp.call - - if to == UNTRACKED - error = "#{expression.inspect} didn't changed" - error = "#{message}.\n#{error}" if message - assert_not_equal before, after, error - else - error = "#{expression.inspect} didn't change to #{to}" - error = "#{message}.\n#{error}" if message - assert to === after, error - end - - retval - end - - # Assertion that the result of evaluating an expression is changed before - # and after invoking the passed in block. - # - # assert_no_changes 'Status.all_good?' do - # post :create, params: { status: { ok: true } } - # end - # - # An error message can be specified. - # - # assert_no_changes -> { Status.all_good? }, 'Expected the status to be good' do - # post :create, params: { status: { ok: false } } - # end - def assert_no_changes(expression, message = nil, &block) - exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) } - - before = exp.call - retval = yield - after = exp.call - - error = "#{expression.inspect} did change to #{after}" - error = "#{message}.\n#{error}" if message - assert_equal before, after, error - - retval - end - end - end -end diff --git a/test/support/task_test_case.rb b/test/support/task_test_case.rb deleted file mode 100644 index 8c539a90a..000000000 --- a/test/support/task_test_case.rb +++ /dev/null @@ -1,14 +0,0 @@ -class TaskTestCase < ActiveSupport::TestCase - setup do - # Rake tasks usually display some results, which mixes up with test results. - # This suppresses default stdout and makes Rails.env.test? checks unnecessary. - @original_stdout = $stdout - $stdout = File.open(File::NULL, 'w') - ActiveSupport::Deprecation.warn('`TaskTestCase` class will be removed soon.' \ - ' Use `capture_io` and `assert_output` instead') - end - - teardown do - $stdout = @original_stdout - end -end diff --git a/test/system/admin_area/api_users/new_test.rb b/test/system/admin_area/api_users/new_test.rb deleted file mode 100644 index aed012fdc..000000000 --- a/test/system/admin_area/api_users/new_test.rb +++ /dev/null @@ -1,25 +0,0 @@ -require 'test_helper' - -class AdminAreaNewApiUserTest < ApplicationSystemTestCase - setup do - sign_in users(:admin) - end - - def test_new_api_user_creation_with_required_params - visit admin_api_users_url - click_link_or_button 'New API user' - - fill_in 'Username', with: 'newtest' - fill_in 'Password', with: 'testtest' - find('#api_user_registrar_id', visible: false).set(registrars(:bestnames).id) - - assert_difference 'ApiUser.count' do - click_link_or_button 'Save' - end - - assert_current_path admin_api_user_path(ApiUser.last) - assert_text 'Record created' - assert_text 'Username newtest' - assert_text 'Password testtest' - end -end \ No newline at end of file diff --git a/test/system/admin_area/api_users_test.rb b/test/system/admin_area/api_users_test.rb new file mode 100644 index 000000000..d79434ef6 --- /dev/null +++ b/test/system/admin_area/api_users_test.rb @@ -0,0 +1,14 @@ +require 'application_system_test_case' + +class AdminApiUsersSystemTest < ApplicationSystemTestCase + setup do + sign_in users(:admin) + end + + def test_shows_api_user_list + visit admin_api_users_path + + api_user = users(:api_bestnames) + assert_link api_user.username, href: admin_registrar_api_user_path(api_user.registrar, api_user) + end +end diff --git a/test/system/admin_area/bank_statement_test.rb b/test/system/admin_area/bank_statement_test.rb new file mode 100644 index 000000000..53cbcc177 --- /dev/null +++ b/test/system/admin_area/bank_statement_test.rb @@ -0,0 +1,16 @@ +require 'application_system_test_case' + +class AdminAreaBankStatementTest < ApplicationSystemTestCase + setup do + sign_in users(:admin) + travel_to Time.zone.parse('2010-07-05 00:30:00') + end + + def test_import_statement + assert_difference 'BankStatement.count', 1 do + visit import_admin_bank_statements_path + attach_file 'Th6 file', Rails.root.join('test', 'fixtures', 'files', 'bank_statement_test.txt').to_s + click_link_or_button 'Save' + end + end +end diff --git a/test/system/admin_area/contact_versions_test.rb b/test/system/admin_area/contact_versions_test.rb index 5028b83fe..2559a203f 100644 --- a/test/system/admin_area/contact_versions_test.rb +++ b/test/system/admin_area/contact_versions_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class ContactVersionsTest < ApplicationSystemTestCase def setup @@ -18,8 +18,8 @@ class ContactVersionsTest < ApplicationSystemTestCase def create_contact_with_history sql = <<-SQL.squish - INSERT INTO contacts (id, code, email, auth_info, registrar_id) - VALUES (75, 'test_code', 'test@inbox.test', '8b4d462aa04194ca78840a', #{@registrar.id}); + INSERT INTO contacts (id, name, code, email, auth_info, registrar_id) + VALUES (75, 'test_name', 'test_code', 'test@inbox.test', '8b4d462aa04194ca78840a', #{@registrar.id}); INSERT INTO log_contacts (item_type, item_id, event, whodunnit, object, object_changes, created_at, session, children, ident_updated_at, uuid) @@ -55,4 +55,4 @@ class ContactVersionsTest < ApplicationSystemTestCase assert_text 'Best Names' assert_text '23.04.18, 18:50 update 1-AdminUser' end -end \ No newline at end of file +end diff --git a/test/system/admin_area/contacts_test.rb b/test/system/admin_area/contacts_test.rb index 7ace0b7ec..d98882dff 100644 --- a/test/system/admin_area/contacts_test.rb +++ b/test/system/admin_area/contacts_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class AdminContactsTest < ApplicationSystemTestCase def setup diff --git a/test/system/admin_area/domain_versions_test.rb b/test/system/admin_area/domain_versions_test.rb index 0d7637f45..8ff90a562 100644 --- a/test/system/admin_area/domain_versions_test.rb +++ b/test/system/admin_area/domain_versions_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class DomainVersionsTest < ApplicationSystemTestCase def setup @@ -18,12 +18,12 @@ class DomainVersionsTest < ApplicationSystemTestCase def create_domain_with_history sql = <<-SQL.squish - INSERT INTO contacts (id, code, email, auth_info, registrar_id) - VALUES (54, 'test_code', 'test@inbox.test', '8b4d462aa04194ca78840a', #{@registrar.id}); + INSERT INTO contacts (id, name, code, email, auth_info, registrar_id) + VALUES (54, 'test_code', 'test_name', 'test@inbox.test', '8b4d462aa04194ca78840a', #{@registrar.id}); - INSERT INTO domains (id, registrar_id, valid_to, registrant_id, + INSERT INTO domains (id, name, name_puny, name_dirty, registrar_id, valid_to, registrant_id, transfer_code) - VALUES (54, #{@registrar.id}, '2018-06-23T12:14:02.732+03:00', 54, 'transfer_code'); + VALUES (54, 'any.test', 'any.test', 'any.test', #{@registrar.id}, '2018-06-23T12:14:02.732+03:00', 54, 'transfer_code'); INSERT INTO log_domains (item_type, item_id, event, whodunnit, object, object_changes, created_at, session, children) @@ -59,4 +59,4 @@ class DomainVersionsTest < ApplicationSystemTestCase assert_text 'Best Names' assert_text '23.04.18, 18:50 update 1-AdminUser' end -end \ No newline at end of file +end diff --git a/test/system/admin_area/domains/details_test.rb b/test/system/admin_area/domains/details_test.rb index 49fada58e..835d213b3 100644 --- a/test/system/admin_area/domains/details_test.rb +++ b/test/system/admin_area/domains/details_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class AdminAreaDomainDetailsTest < ApplicationSystemTestCase setup do diff --git a/test/system/admin_area/domains/force_delete_test.rb b/test/system/admin_area/domains/force_delete_test.rb index 561e4d47a..4ccc10923 100644 --- a/test/system/admin_area/domains/force_delete_test.rb +++ b/test/system/admin_area/domains/force_delete_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class AdminAreaDomainForceDeleteTest < ApplicationSystemTestCase include ActionMailer::TestHelper @@ -28,9 +28,18 @@ class AdminAreaDomainForceDeleteTest < ApplicationSystemTestCase end end - def test_notifies_registrant_and_admin_contacts_by_email_by_default + def test_notifies_registrant_and_admin_contacts_by_email_if_fast_delete assert_emails 1 do visit edit_admin_domain_url(@domain) + find(:css, '#soft_delete').set(false) + click_link_or_button 'Force delete domain' + end + end + + def test_notifies_registrant_and_admin_contacts_by_email_if_soft_delete + assert_emails 0 do + visit edit_admin_domain_url(@domain) + find(:css, '#soft_delete').set(true) click_link_or_button 'Force delete domain' end end @@ -62,4 +71,4 @@ class AdminAreaDomainForceDeleteTest < ApplicationSystemTestCase assert_no_button 'Schedule force delete' assert_no_link 'Schedule force delete' end -end \ No newline at end of file +end diff --git a/test/system/admin_area/domains/legal_doc_test.rb b/test/system/admin_area/domains/legal_doc_test.rb new file mode 100644 index 000000000..00cc7cc3a --- /dev/null +++ b/test/system/admin_area/domains/legal_doc_test.rb @@ -0,0 +1,21 @@ +require 'application_system_test_case' + +class AdminAreaDomainsLegalDocTest < ApplicationSystemTestCase + setup do + sign_in users(:admin) + @domain = domains(:shop) + @document = LegalDocument.create( + document_type: 'pdf', + documentable_id: @domain.id, + documentable_type: 'Domain', + path: '\zzz\zzz' + ) + end + + def test_absent_doc_downloading_without_errors + visit admin_domain_url(@domain) + assert_nothing_raised do + click_on "#{@document.created_at}" + end + end +end diff --git a/test/system/admin_area/domains/registry_lock_test.rb b/test/system/admin_area/domains/registry_lock_test.rb index ce09c445c..6a34c23b4 100644 --- a/test/system/admin_area/domains/registry_lock_test.rb +++ b/test/system/admin_area/domains/registry_lock_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class AdminAreaRegistryLockTest < JavaScriptApplicationSystemTestCase def setup @@ -10,10 +10,6 @@ class AdminAreaRegistryLockTest < JavaScriptApplicationSystemTestCase @domain = domains(:airport) end - def teardown - travel_back - end - def test_does_not_have_link_when_domain_is_not_locked visit edit_admin_domain_path(@domain) click_link_or_button('Actions') diff --git a/test/system/admin_area/domains_test.rb b/test/system/admin_area/domains_test.rb index 7037a076d..05e7d60f3 100644 --- a/test/system/admin_area/domains_test.rb +++ b/test/system/admin_area/domains_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class AdminDomainsTestTest < ApplicationSystemTestCase setup do @@ -7,10 +7,6 @@ class AdminDomainsTestTest < ApplicationSystemTestCase @domain = domains(:shop) end - teardown do - travel_back - end - def test_shows_details visit admin_domain_path(@domain) assert_field nil, with: @domain.transfer_code @@ -39,4 +35,15 @@ class AdminDomainsTestTest < ApplicationSystemTestCase assert_text 'deleteCandidate status has been removed' assert_no_link 'Remove deleteCandidate status' end + + def test_remove_domain_status + @domain.update!(statuses: [DomainStatus::SERVER_REGISTRANT_CHANGE_PROHIBITED]) + + visit edit_admin_domain_url(@domain) + + click_link_or_button 'Delete' + click_link_or_button 'Save' + + assert_text 'Domain updated!' + end end diff --git a/test/system/admin_area/invoices_test.rb b/test/system/admin_area/invoices_test.rb index 8fef3cddb..814f95d4a 100644 --- a/test/system/admin_area/invoices_test.rb +++ b/test/system/admin_area/invoices_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class AdminAreaInvoicesTest < ApplicationSystemTestCase include ActionMailer::TestHelper diff --git a/test/system/admin_area/prices_test.rb b/test/system/admin_area/prices_test.rb new file mode 100644 index 000000000..dbb91966a --- /dev/null +++ b/test/system/admin_area/prices_test.rb @@ -0,0 +1,47 @@ +require 'application_system_test_case' + +class AdminAreaPricesTest < ApplicationSystemTestCase + setup do + sign_in users(:admin) + @price = billing_prices(:create_one_month) + end + + def test_adds_new_price_with_required_attributes + effective_date = Date.parse('2010-07-06') + assert_nil Billing::Price.find_by(valid_from: effective_date) + + visit admin_prices_url + click_on 'New price' + + select dns_zones(:one).origin, from: 'Zone' + select Billing::Price.operation_categories.first, from: 'Operation category' + select '3 months', from: 'Duration' + fill_in 'Price', with: '1' + fill_in 'Valid from', with: effective_date + click_on 'Create price' + + assert_text 'Price has been created' + assert_text I18n.localize(effective_date) + end + + def test_changes_price + new_effective_date = Date.parse('2010-07-06') + assert_not_equal new_effective_date, @price.valid_from + + visit admin_prices_url + find('.edit-price-btn').click + fill_in 'Valid from', with: new_effective_date + click_on 'Update price' + + assert_text 'Price has been updated' + assert_text I18n.localize(new_effective_date) + end + + def test_expires_price + visit admin_prices_url + find('.edit-price-btn').click + click_on 'Expire' + + assert_text 'Price has been expired' + end +end diff --git a/test/system/admin_area/protected_area_test.rb b/test/system/admin_area/protected_area_test.rb index 9390348f0..f3375776a 100644 --- a/test/system/admin_area/protected_area_test.rb +++ b/test/system/admin_area/protected_area_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class AdminAreaProtectedAreaTest < ApplicationSystemTestCase def test_anonymous_user_is_asked_to_authenticate_when_navigating_to_protected_area diff --git a/test/system/admin_area/registrars/api_users_test.rb b/test/system/admin_area/registrars/api_users_test.rb new file mode 100644 index 000000000..5d833dde2 --- /dev/null +++ b/test/system/admin_area/registrars/api_users_test.rb @@ -0,0 +1,75 @@ +require 'application_system_test_case' + +class AdminRegistrarsApiUsersSystemTest < ApplicationSystemTestCase + setup do + sign_in users(:admin) + end + + def test_creates_new_api_user_with_required_attributes + username = 'john' + registrar = registrars(:bestnames) + + visit admin_registrar_path(registrar) + click_on 'New API user' + + fill_in 'Username', with: username + fill_in 'Password', with: valid_password + click_on 'Create API user' + + assert_text 'API user has been successfully created' + assert_text "Username #{username}" + new_api_user = ApiUser.last + assert_current_path admin_registrar_api_user_path(registrar, new_api_user) + end + + def test_shows_api_user_details + api_user = users(:api_bestnames) + + visit admin_registrar_path(api_user.registrar) + click_on api_user.username + + assert_text "Username #{api_user.username}" + assert_text "Password #{api_user.plain_text_password}" + assert_link api_user.registrar.name, href: admin_registrar_path(api_user.registrar) + assert_text "Role #{api_user.roles.first}" + assert_text "Active #{api_user.active}" + end + + def test_updates_api_user + api_user = users(:api_bestnames) + new_username = 'new username' + assert_not_equal new_username, api_user.username + + visit admin_registrar_api_user_path(api_user.registrar, api_user) + click_link_or_button 'Edit' + fill_in 'Username', with: new_username + click_link_or_button 'Update API user' + + assert_text 'API user has been successfully updated' + assert_text "Username #{new_username}" + assert_current_path admin_registrar_api_user_path(api_user.registrar, api_user) + end + + def test_deletes_api_user + api_user = unassociated_api_user + + visit admin_registrar_api_user_path(api_user.registrar, api_user) + click_on 'Delete' + + assert_text 'API user has been successfully deleted' + assert_current_path admin_registrar_path(api_user.registrar) + end + + private + + def unassociated_api_user + new_api_user = users(:api_bestnames).dup + new_api_user.username = "unique-#{rand(100)}" + new_api_user.save! + new_api_user + end + + def valid_password + 'testtest' + end +end diff --git a/test/system/admin_area/registrars_test.rb b/test/system/admin_area/registrars_test.rb index 3d3e1c4f0..570517078 100644 --- a/test/system/admin_area/registrars_test.rb +++ b/test/system/admin_area/registrars_test.rb @@ -1,13 +1,18 @@ -require 'test_helper' +require 'application_system_test_case' class AdminRegistrarsSystemTest < ApplicationSystemTestCase include ActionView::Helpers::NumberHelper setup do @registrar = registrars(:bestnames) + @original_default_language = Setting.default_language sign_in users(:admin) end + teardown do + Setting.default_language = @original_default_language + end + def test_creates_new_registrar assert_nil Registrar.find_by(name: 'Acme Ltd') diff --git a/test/system/admin_area/reserved_domains/new_test.rb b/test/system/admin_area/reserved_domains/new_test.rb index 05b740b86..a6a5a9bfd 100644 --- a/test/system/admin_area/reserved_domains/new_test.rb +++ b/test/system/admin_area/reserved_domains/new_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class AdminAreaReservedDomainsNewTest < ApplicationSystemTestCase setup do diff --git a/test/system/admin_area/settings_test.rb b/test/system/admin_area/settings_test.rb new file mode 100644 index 000000000..0097381d9 --- /dev/null +++ b/test/system/admin_area/settings_test.rb @@ -0,0 +1,13 @@ +require 'application_system_test_case' + +class AdminAreaSettingsTest < ApplicationSystemTestCase + setup do + sign_in users(:admin) + end + + def test_saves_settings + visit admin_settings_url + click_link_or_button 'Save' + assert_text 'Settings have been successfully updated' + end +end diff --git a/test/system/admin_area/sign_in_test.rb b/test/system/admin_area/sign_in_test.rb index dd264aa5e..67a3f0d36 100644 --- a/test/system/admin_area/sign_in_test.rb +++ b/test/system/admin_area/sign_in_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class AdminAreaSignInTest < ApplicationSystemTestCase setup do diff --git a/test/system/admin_area/sign_out_test.rb b/test/system/admin_area/sign_out_test.rb index f85ea0bd2..45a60b12c 100644 --- a/test/system/admin_area/sign_out_test.rb +++ b/test/system/admin_area/sign_out_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class AdminAreaSignOutTest < ApplicationSystemTestCase setup do diff --git a/test/system/admin_area/zones_test.rb b/test/system/admin_area/zones_test.rb new file mode 100644 index 000000000..d7ad9d690 --- /dev/null +++ b/test/system/admin_area/zones_test.rb @@ -0,0 +1,46 @@ +require 'application_system_test_case' + +class AdminAreaZonesTest < ApplicationSystemTestCase + setup do + sign_in users(:admin) + @zone = dns_zones(:one) + end + + def test_creates_new_zone_with_required_attributes + origin = 'com.test' + assert_nil DNS::Zone.find_by(origin: origin) + + visit admin_zones_url + click_on 'New zone' + + fill_in 'Origin', with: origin + fill_in 'Ttl', with: '1' + fill_in 'Refresh', with: '1' + fill_in 'Retry', with: '1' + fill_in 'Expire', with: '1' + fill_in 'Minimum ttl', with: '1' + fill_in 'Email', with: 'new.registry.test' + fill_in 'Master nameserver', with: 'any.test' + click_on 'Create zone' + + assert_text 'Zone has been created' + assert_text origin + end + + def test_changes_zone + new_email = 'new@registry.test' + assert_not_equal new_email, @zone.email + + visit admin_zones_url + click_on 'admin-edit-zone-btn' + fill_in 'Email', with: new_email + click_on 'Update zone' + + assert_text 'Zone has been updated' + end + + def test_origin_is_not_editable + visit edit_admin_zone_url(@zone) + assert_no_field 'Origin' + end +end diff --git a/test/system/registrant_area/contacts/details_test.rb b/test/system/registrant_area/contacts/details_test.rb index 1198de6c4..bf96046a6 100644 --- a/test/system/registrant_area/contacts/details_test.rb +++ b/test/system/registrant_area/contacts/details_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class RegistrantAreaContactDetailsTest < ApplicationSystemTestCase setup do @@ -24,18 +24,10 @@ class RegistrantAreaContactDetailsTest < ApplicationSystemTestCase end def test_registrant_user_cannot_access_contact_when_given_domain_belongs_to_another_user - suppress(ActionView::Template::Error) do + suppress(ActiveRecord::RecordNotFound) do visit registrant_domain_contact_url(domains(:metro), @contact) assert_response :not_found assert_no_text 'Name John' end end - - def test_unmanaged_contact_cannot_be_accessed - @contact.update!(ident: '12345') - - assert_raises ActiveRecord::RecordNotFound do - visit registrant_domain_contact_url(@domain, @contact) - end - end -end \ No newline at end of file +end diff --git a/test/system/registrant_area/contacts/update_test.rb b/test/system/registrant_area/contacts/update_test.rb index 897600cd9..07115579b 100644 --- a/test/system/registrant_area/contacts/update_test.rb +++ b/test/system/registrant_area/contacts/update_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class RegistrantAreaContactUpdateTest < ApplicationIntegrationTest setup do @@ -6,7 +6,7 @@ class RegistrantAreaContactUpdateTest < ApplicationIntegrationTest @contact = contacts(:john) sign_in users(:registrant) - @original_address_processing_setting = Setting.address_processing + @original_address_processing = Setting.address_processing @original_fax_enabled_setting = ENV['fax_enabled'] @original_registrant_api_base_url_setting = ENV['registrant_api_base_url'] @@ -14,7 +14,7 @@ class RegistrantAreaContactUpdateTest < ApplicationIntegrationTest end teardown do - Setting.address_processing = @original_address_processing_setting + Setting.address_processing = @original_address_processing ENV['fax_enabled'] = @original_fax_enabled_setting ENV['registrant_api_base_url'] = @original_registrant_api_base_url_setting end @@ -31,7 +31,7 @@ class RegistrantAreaContactUpdateTest < ApplicationIntegrationTest stub_auth_request request_body = { name: 'new name', email: 'new@inbox.test', phone: '+666.6' }.to_json - headers = { 'Content-Type' => Mime::JSON, + headers = { 'Content-Type' => Mime[:json], 'Authorization' => 'Bearer test-access-token' } url = "https://api.test/api/v1/registrant/contacts/#{@contact.uuid}" update_request_stub = stub_request(:patch, url).with(body: request_body, headers: headers) @@ -115,7 +115,7 @@ class RegistrantAreaContactUpdateTest < ApplicationIntegrationTest country_code: 'AT', state: 'new state', } }.to_json - headers = { 'Content-type' => 'application/json', + headers = { 'Content-type' => Mime[:json], 'Authorization' => 'Bearer test-access-token' } url = "https://api.test/api/v1/registrant/contacts/#{@contact.uuid}" update_request_stub = stub_request(:patch, url).with(body: request_body, headers: headers) @@ -141,14 +141,6 @@ class RegistrantAreaContactUpdateTest < ApplicationIntegrationTest assert_no_field 'Street' end - def test_unmanaged_contact_cannot_be_updated - @contact.update!(ident: '12345') - - assert_raises ActiveRecord::RecordNotFound do - visit registrant_domain_contact_url(@domain, @contact) - end - end - def test_fail_gracefully stub_auth_request @@ -174,7 +166,7 @@ class RegistrantAreaContactUpdateTest < ApplicationIntegrationTest body = { ident: '1234', first_name: 'Registrant', last_name: 'User' } stub_request(:post, 'https://api.test/api/v1/registrant/auth/eid').with(body: body) .to_return(body: { access_token: 'test-access-token' }.to_json, - headers: { 'Content-type' => 'application/json' }, + headers: { 'Content-type' => Mime[:json] }, status: 200) end end diff --git a/test/system/registrant_area/domains/details_test.rb b/test/system/registrant_area/domains/details_test.rb index ef9197541..5b2e30ba3 100644 --- a/test/system/registrant_area/domains/details_test.rb +++ b/test/system/registrant_area/domains/details_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class RegistrantAreaDomainDetailsTest < ApplicationSystemTestCase setup do diff --git a/test/system/registrant_area/domains/domain_delete_confirms_test.rb b/test/system/registrant_area/domains/domain_delete_confirms_test.rb new file mode 100644 index 000000000..0eb61ada8 --- /dev/null +++ b/test/system/registrant_area/domains/domain_delete_confirms_test.rb @@ -0,0 +1,41 @@ +require 'application_system_test_case' + +class DomainDeleteConfirmsTest < ApplicationSystemTestCase + setup do + @user = users(:registrant) + sign_in @user + + @domain = domains(:shop) + @domain.registrant_verification_asked!('\n', @user.id) + @domain.pending_delete! + end + + def test_enqueues_approve_job_after_verification + visit registrant_domain_delete_confirm_url(@domain.id, token: @domain.registrant_verification_token) + + click_on 'Confirm domain delete' + assert_text 'Domain registrant change has successfully received.' + + @domain.reload + assert_includes @domain.statuses, 'serverHold' + end + + def test_enqueues_reject_job_after_verification + visit registrant_domain_delete_confirm_url(@domain.id, token: @domain.registrant_verification_token) + + click_on 'Reject domain delete' + assert_text 'Domain registrant change has been rejected successfully.' + + @domain.reload + assert_equal ['ok'], @domain.statuses + end + + def test_saves_whodunnit_info_after_verifivation + visit registrant_domain_delete_confirm_url(@domain.id, token: @domain.registrant_verification_token) + token = @domain.registrant_verification_token + click_on 'Confirm domain delete' + assert_text 'Domain registrant change has successfully received.' + + refute RegistrantVerification.find_by(verification_token:token).updator_str.empty? + end +end diff --git a/test/system/registrant_area/domains/list_test.rb b/test/system/registrant_area/domains/list_test.rb index 54ca979b3..805b130de 100644 --- a/test/system/registrant_area/domains/list_test.rb +++ b/test/system/registrant_area/domains/list_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' CompanyRegisterClientStub = Struct.new(:any_method) do def representation_rights(citizen_personal_code:, citizen_country_code:) diff --git a/test/system/registrant_area/domains_test.rb b/test/system/registrant_area/domains_test.rb index 175cb61ae..fa151c89e 100644 --- a/test/system/registrant_area/domains_test.rb +++ b/test/system/registrant_area/domains_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class RegistrantDomainsTest < ApplicationSystemTestCase setup do diff --git a/test/system/registrant_area/layout_test.rb b/test/system/registrant_area/layout_test.rb index 0fedaaefe..9df8028e3 100644 --- a/test/system/registrant_area/layout_test.rb +++ b/test/system/registrant_area/layout_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class RegistrantLayoutTest < ApplicationSystemTestCase def setup diff --git a/test/system/registrar_area/account_test.rb b/test/system/registrar_area/account_test.rb index 81db3ed4b..708f8dc8f 100644 --- a/test/system/registrar_area/account_test.rb +++ b/test/system/registrar_area/account_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class RegistrarAccountTest < ApplicationSystemTestCase setup do diff --git a/test/system/registrar_area/base_test.rb b/test/system/registrar_area/base_test.rb new file mode 100644 index 000000000..67b19a044 --- /dev/null +++ b/test/system/registrar_area/base_test.rb @@ -0,0 +1,41 @@ +require 'application_system_test_case' + +class RegistrarAreaBaseTestTest < ApplicationSystemTestCase + setup do + @original_registrar_area_ip_whitelist = Setting.registrar_ip_whitelist_enabled + end + + teardown do + Setting.registrar_ip_whitelist_enabled = @original_registrar_area_ip_whitelist + end + + def test_user_cannot_access_without_ip_address_being_whitelisted + Setting.registrar_ip_whitelist_enabled = true + WhiteIp.delete_all + + visit new_registrar_user_session_url + + assert_text 'Access denied from IP 127.0.0.1' + assert_no_button 'Login' + end + + def test_user_can_access_when_ip_is_whitelisted + white_ips(:one).update!(ipv4: '127.0.0.1', interfaces: [WhiteIp::REGISTRAR]) + Setting.registrar_ip_whitelist_enabled = true + + visit new_registrar_user_session_url + + assert_no_text 'Access denied from IP 127.0.0.1' + assert_button 'Login' + end + + def test_user_can_access_when_ip_is_not_whitelisted_and_whitelist_is_disabled + Setting.registrar_ip_whitelist_enabled = false + WhiteIp.delete_all + + visit new_registrar_user_session_url + + assert_no_text 'Access denied from IP 127.0.0.1' + assert_button 'Login' + end +end diff --git a/test/system/registrar_area/billing/balance_top_up_test.rb b/test/system/registrar_area/billing/balance_top_up_test.rb index 2d44e8328..be378df97 100644 --- a/test/system/registrar_area/billing/balance_top_up_test.rb +++ b/test/system/registrar_area/billing/balance_top_up_test.rb @@ -1,12 +1,16 @@ -require 'test_helper' +require 'application_system_test_case' class BalanceTopUpTest < ApplicationSystemTestCase setup do sign_in users(:api_bestnames) + @original_registry_vat_rate = Setting.registry_vat_prc + end + + teardown do + Setting.registry_vat_prc = @original_registry_vat_rate end def test_creates_new_invoice - original_vat_prc = Setting.registry_vat_prc Setting.registry_vat_prc = 0.1 visit registrar_invoices_url @@ -22,7 +26,5 @@ class BalanceTopUpTest < ApplicationSystemTestCase assert_equal BigDecimal(10), invoice.vat_rate assert_equal BigDecimal('28.05'), invoice.total assert_text 'Please pay the following invoice' - - Setting.registry_vat_prc = original_vat_prc end end diff --git a/test/system/registrar_area/bulk_change/bulk_transfer_test.rb b/test/system/registrar_area/bulk_change/bulk_transfer_test.rb index 3a663a9bc..69b755499 100644 --- a/test/system/registrar_area/bulk_change/bulk_transfer_test.rb +++ b/test/system/registrar_area/bulk_change/bulk_transfer_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class RegistrarAreaBulkTransferTest < ApplicationSystemTestCase setup do @@ -7,7 +7,7 @@ class RegistrarAreaBulkTransferTest < ApplicationSystemTestCase def test_transfer_multiple_domains_in_bulk request_body = { data: { domainTransfers: [{ domainName: 'shop.test', transferCode: '65078d5' }] } } - headers = { 'Content-type' => 'application/json' } + headers = { 'Content-type' => Mime[:json] } request_stub = stub_request(:post, /domain_transfers/).with(body: request_body, headers: headers, basic_auth: ['test_goodnames', 'testtest']) @@ -28,7 +28,7 @@ class RegistrarAreaBulkTransferTest < ApplicationSystemTestCase def test_fail_gracefully body = { errors: [{ title: 'epic fail' }] }.to_json - headers = { 'Content-type' => 'application/json' } + headers = { 'Content-type' => Mime[:json] } stub_request(:post, /domain_transfers/).to_return(status: 400, body: body, headers: headers) visit registrar_domains_url diff --git a/test/system/registrar_area/bulk_change/nameserver_test.rb b/test/system/registrar_area/bulk_change/nameserver_test.rb index c5789a969..d6b3170d5 100644 --- a/test/system/registrar_area/bulk_change/nameserver_test.rb +++ b/test/system/registrar_area/bulk_change/nameserver_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class RegistrarAreaNameserverBulkChangeTest < ApplicationSystemTestCase setup do @@ -12,7 +12,7 @@ class RegistrarAreaNameserverBulkChangeTest < ApplicationSystemTestCase ipv4: %w[192.0.2.55 192.0.2.56], ipv6: %w[2001:db8::55 2001:db8::56] } } } request_stub = stub_request(:put, /registrar\/nameservers/).with(body: request_body, - headers: { 'Content-type' => 'application/json' }, + headers: { 'Content-type' => Mime[:json] }, basic_auth: ['test_goodnames', 'testtest']) .to_return(body: { data: [{ type: 'nameserver', @@ -38,7 +38,7 @@ class RegistrarAreaNameserverBulkChangeTest < ApplicationSystemTestCase def test_fails_gracefully stub_request(:put, /registrar\/nameservers/).to_return(status: 400, body: { errors: [{ title: 'epic fail' }] }.to_json, - headers: { 'Content-type' => 'application/json' }) + headers: { 'Content-type' => Mime[:json] }) visit registrar_domains_url click_link 'Bulk change' diff --git a/test/system/registrar_area/bulk_change/tech_contact_test.rb b/test/system/registrar_area/bulk_change/tech_contact_test.rb index 0b68b9db2..c678e8f34 100644 --- a/test/system/registrar_area/bulk_change/tech_contact_test.rb +++ b/test/system/registrar_area/bulk_change/tech_contact_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class RegistrarAreaTechContactBulkChangeTest < ApplicationSystemTestCase setup do @@ -31,7 +31,7 @@ class RegistrarAreaTechContactBulkChangeTest < ApplicationSystemTestCase stub_request(:patch, /domains\/contacts/) .to_return(status: 400, body: { error: { message: 'epic fail' } }.to_json, - headers: { 'Content-type' => 'application/json' }) + headers: { 'Content-type' => Mime[:json] }) visit registrar_domains_url click_link 'Bulk change' diff --git a/test/system/registrar_area/domains_test.rb b/test/system/registrar_area/domains_test.rb index a01dd576b..7a2f5f7f1 100644 --- a/test/system/registrar_area/domains_test.rb +++ b/test/system/registrar_area/domains_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class RegistrarDomainsTest < ApplicationSystemTestCase def test_downloads_domain_list_as_csv @@ -14,8 +14,8 @@ class RegistrarDomainsTest < ApplicationSystemTestCase CSV visit registrar_domains_url - click_button 'Download as CSV' - assert_equal 'attachment; filename="Domains_2010-07-05_10.30.csv"', response_headers['Content-Disposition'] + click_button 'Download CSV' + assert_equal "attachment; filename=\"Domains_2010-07-05_10.30.csv\"; filename*=UTF-8''Domains_2010-07-05_10.30.csv", response_headers['Content-Disposition'] assert_equal expected_csv, page.body end end diff --git a/test/system/registrar_area/invoices/list_test.rb b/test/system/registrar_area/invoices/list_test.rb index e63d8c1a4..bb68acb2f 100644 --- a/test/system/registrar_area/invoices/list_test.rb +++ b/test/system/registrar_area/invoices/list_test.rb @@ -1,12 +1,11 @@ -require 'test_helper' +require 'application_system_test_case' class ListInvoicesTest < ApplicationSystemTestCase setup do @user = users(:api_bestnames) - sign_in @user - @invoice = invoices(:one) - eliminate_effect_of_other_invoices + + sign_in @user end def test_show_balance @@ -14,31 +13,23 @@ class ListInvoicesTest < ApplicationSystemTestCase assert_text "Your current account balance is 100,00 EUR" end - def test_show_invoices_of_current_registrar - registrar = registrars(:bestnames) - @user.update!(registrar: registrar) - @invoice.update!(seller: registrar) + def test_shows_invoice_owned_by_current_user + owning_registrar = registrars(:bestnames) + assert_equal owning_registrar, @user.registrar + @invoice.update!(buyer: owning_registrar) visit registrar_invoices_url - assert_css '.invoice' + assert_text @invoice.to_s end - def test_do_not_show_invoices_of_other_registrars - registrar = registrars(:goodnames) - @user.update!(registrar: registrar) - @invoice.update!(seller: registrar) + def test_hides_invoice_owned_by_other_user + other_registrar = registrars(:goodnames) + assert_not_equal other_registrar, @user.registrar + @invoice.update!(buyer: other_registrar) visit registrar_invoices_url - assert_no_css '.invoice' - end - - private - - def eliminate_effect_of_other_invoices - Invoice.connection.disable_referential_integrity do - Invoice.delete_all("id != #{@invoice.id}") - end + assert_no_text @invoice.to_s end end \ No newline at end of file diff --git a/test/system/registrar_area/invoices/new_invoice_payment_test.rb b/test/system/registrar_area/invoices/new_invoice_payment_test.rb index 6933ff9ad..ea4b924fe 100644 --- a/test/system/registrar_area/invoices/new_invoice_payment_test.rb +++ b/test/system/registrar_area/invoices/new_invoice_payment_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class NewInvoicePaymentTest < ApplicationSystemTestCase def setup @@ -26,7 +26,7 @@ class NewInvoicePaymentTest < ApplicationSystemTestCase def test_create_new_SEB_payment create_invoice_and_visit_its_page - click_link_or_button 'Seb' + click_link_or_button 'seb' form = page.find('form') assert_equal('https://www.seb.ee/cgi-bin/dv.sh/ipank.r', form['action']) assert_equal('post', form['method']) @@ -35,7 +35,7 @@ class NewInvoicePaymentTest < ApplicationSystemTestCase def test_create_new_Every_Pay_payment create_invoice_and_visit_its_page - click_link_or_button 'Every pay' + click_link_or_button 'every_pay' expected_hmac_fields = 'account_id,amount,api_username,callback_url,' + 'customer_url,hmac_fields,nonce,order_reference,timestamp,transaction_type' diff --git a/test/system/registrar_area/invoices/new_test.rb b/test/system/registrar_area/invoices/new_test.rb index a5a72fbe8..26ab34385 100644 --- a/test/system/registrar_area/invoices/new_test.rb +++ b/test/system/registrar_area/invoices/new_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class NewInvoiceTest < ApplicationSystemTestCase def setup diff --git a/test/system/registrar_area/invoices_test.rb b/test/system/registrar_area/invoices_test.rb index 02df5da82..e64204165 100644 --- a/test/system/registrar_area/invoices_test.rb +++ b/test/system/registrar_area/invoices_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class RegistrarAreaInvoicesTest < ApplicationSystemTestCase include ActionMailer::TestHelper diff --git a/test/system/registrar_area/protected_area_test.rb b/test/system/registrar_area/protected_area_test.rb index f3ec06302..f1be6008d 100644 --- a/test/system/registrar_area/protected_area_test.rb +++ b/test/system/registrar_area/protected_area_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class RegistrarAreaProtectedAreaTest < ApplicationSystemTestCase def test_anonymous_user_is_asked_to_authenticate_when_navigating_to_protected_area diff --git a/test/system/registrar_area/settings/balance_auto_reload_test.rb b/test/system/registrar_area/settings/balance_auto_reload_test.rb index a5ad6dec1..066fb6186 100644 --- a/test/system/registrar_area/settings/balance_auto_reload_test.rb +++ b/test/system/registrar_area/settings/balance_auto_reload_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class RegistrarAreaSettingsBalanceAutoReloadTest < ApplicationSystemTestCase setup do diff --git a/test/system/registrar_area/sign_in/mobile_id_test.rb b/test/system/registrar_area/sign_in/mobile_id_test.rb index ecca00c56..171172b2c 100644 --- a/test/system/registrar_area/sign_in/mobile_id_test.rb +++ b/test/system/registrar_area/sign_in/mobile_id_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class RegistrarAreaMobileIDSignInTest < JavaScriptApplicationSystemTestCase def setup diff --git a/test/system/registrar_area/sign_in/password_test.rb b/test/system/registrar_area/sign_in/password_test.rb index 433c56d9d..a362e98e3 100644 --- a/test/system/registrar_area/sign_in/password_test.rb +++ b/test/system/registrar_area/sign_in/password_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class RegistrarAreaPasswordSignInTest < ApplicationSystemTestCase setup do diff --git a/test/system/registrar_area/sign_out_test.rb b/test/system/registrar_area/sign_out_test.rb index 8fd48db21..040836600 100644 --- a/test/system/registrar_area/sign_out_test.rb +++ b/test/system/registrar_area/sign_out_test.rb @@ -1,4 +1,4 @@ -require 'test_helper' +require 'application_system_test_case' class RegistrarAreaSignOutTest < ApplicationSystemTestCase setup do diff --git a/test/tasks/data_migrations/convert_domain_delete_date_test.rb b/test/tasks/data_migrations/convert_domain_delete_date_test.rb deleted file mode 100644 index a17e1109b..000000000 --- a/test/tasks/data_migrations/convert_domain_delete_date_test.rb +++ /dev/null @@ -1,61 +0,0 @@ -require 'test_helper' - -class ConvertDomainDeleteDateTaskTest < ActiveSupport::TestCase - setup do - @domain = domains(:shop) - end - - def test_moves_domain_delete_date_one_day_ahead - @domain.update!(delete_date: '2010-07-05') - - capture_io do - run_task - end - @domain.reload - - assert_equal Date.parse('2010-07-06'), @domain.delete_date - end - - def test_processes_invalid_domains - @domain = domains(:invalid) - @domain.update_columns(delete_date: '2010-07-05') - - capture_io do - run_task - end - @domain.reload - - assert_equal Date.parse('2010-07-06'), @domain.delete_date - end - - def test_skips_non_expired_domains - @domain.update!(delete_date: nil) - - assert_nothing_raised do - capture_io do - run_task - end - end - end - - def test_output - eliminate_effect_of_all_domains_except(@domain) - @domain.update!(delete_date: '2010-07-05') - - assert_output "Domains processed: 1\n" do - run_task - end - end - - private - - def eliminate_effect_of_all_domains_except(domain) - Domain.connection.disable_referential_integrity do - Domain.delete_all("id != #{domain.id}") - end - end - - def run_task - Rake::Task['data_migrations:convert_domain_delete_date'].execute - end -end \ No newline at end of file diff --git a/test/tasks/emails/verify_email_task_test.rb b/test/tasks/emails/verify_email_task_test.rb new file mode 100644 index 000000000..7cca11845 --- /dev/null +++ b/test/tasks/emails/verify_email_task_test.rb @@ -0,0 +1,63 @@ +require 'test_helper' + +class VerifyEmailTaskTest < ActiveSupport::TestCase + + def setup + @contact = contacts(:john) + @invalid_contact = contacts(:invalid_email) + @contact_verification = @contact.email_verification + @invalid_contact_verification = @invalid_contact.email_verification + + @default_whitelist = Truemail.configure.whitelisted_domains + @default_blacklist = Truemail.configure.blacklisted_domains + Truemail.configure.whitelisted_domains = whitelisted_domains + Truemail.configure.blacklisted_domains = blacklisted_domains + end + + def teardown + Truemail.configure.whitelisted_domains = @default_whitelist + Truemail.configure.blacklisted_domains = @default_blacklist + end + + def domain(email) + Mail::Address.new(email).domain + rescue Mail::Field::IncompleteParseError + nil + end + + def whitelisted_domains + [domain(@contact.email)].reject(&:blank?) + end + + def blacklisted_domains + [domain(@invalid_contact.email)].reject(&:blank?) + end + + def test_tasks_verifies_emails + capture_io { run_task } + + @contact_verification.reload + @invalid_contact_verification.reload + + assert @contact_verification.verified? + assert @invalid_contact_verification.failed? + end + + def test_domain_task_verifies_for_one_domain + capture_io { run_single_domain_task(@contact_verification.domain) } + + @contact_verification.reload + @invalid_contact_verification.reload + + assert @contact_verification.verified? + assert @invalid_contact_verification.not_verified? + end + + def run_task + Rake::Task['verify_email:all_domains'].execute + end + + def run_single_domain_task(domain) + Rake::Task["verify_email:domain"].invoke(domain) + end +end diff --git a/test/tasks/invoices/cancel_overdue_test.rb b/test/tasks/invoices/cancel_overdue_test.rb index 19ef8e0bf..044997ae9 100644 --- a/test/tasks/invoices/cancel_overdue_test.rb +++ b/test/tasks/invoices/cancel_overdue_test.rb @@ -31,7 +31,7 @@ class CancelOverdueInvoicesTaskTest < ActiveSupport::TestCase def eliminate_effect_of_other_invoices Invoice.connection.disable_referential_integrity do - Invoice.delete_all("id != #{@invoice.id}") + Invoice.where("id != #{@invoice.id}").delete_all end end diff --git a/test/tasks/invoices/process_payments_test.rb b/test/tasks/invoices/process_payments_test.rb new file mode 100644 index 000000000..bd447be29 --- /dev/null +++ b/test/tasks/invoices/process_payments_test.rb @@ -0,0 +1,108 @@ +require 'test_helper' + +class ProcessPaymentsTaskTest < ActiveSupport::TestCase + setup do + @payment_amount = payment_amount = 0.1 + @payment_currency = payment_currency = 'EUR' + @payment_date = payment_date = Date.parse('2010-07-05') + @payment_reference_number = payment_reference_number = '13' + @payment_description = payment_description = @invoice_number = '1234' + beneficiary_iban = 'GB33BUKB20201555555555' + + @invoice = create_payable_invoice(number: @invoice_number, + total: payment_amount, + currency: @payment_currency, + reference_no: @payment_reference_number) + Setting.registry_iban = beneficiary_iban + + Lhv::ConnectApi.class_eval do + define_method :credit_debit_notification_messages do + transaction = OpenStruct.new(amount: payment_amount, + currency: payment_currency, + date: payment_date, + payment_reference_number: payment_reference_number, + payment_description: payment_description) + message = OpenStruct.new(bank_account_iban: beneficiary_iban, + credit_transactions: [transaction]) + [message] + end + end + end + + def test_doubles_are_valid + assert Lhv::ConnectApi.method_defined?(:credit_debit_notification_messages) + assert Lhv::ConnectApi::Messages::CreditDebitNotification.method_defined?(:bank_account_iban) + assert Lhv::ConnectApi::Messages::CreditDebitNotification.method_defined?(:credit_transactions) + end + + def test_saves_transactions + assert_difference 'BankStatement.count' do + assert_difference 'BankTransaction.count' do + capture_io { run_task } + end + end + transaction = BankTransaction.last + assert_equal @payment_amount, transaction.sum + assert_equal @payment_currency, transaction.currency + assert_equal @payment_date, transaction.paid_at.to_date + assert_equal @payment_reference_number, transaction.reference_no + assert_equal @payment_description, transaction.description + end + + def test_marks_matched_invoice_as_paid + assert @invoice.unpaid? + + capture_io { run_task } + @invoice.reload + + assert @invoice.paid? + end + + def test_attaches_paid_payment_order_to_invoice + assert @invoice.unpaid? + + capture_io { run_task } + @invoice.reload + + payment_order = @invoice.payment_orders.last + assert_equal 'PaymentOrders::SystemPayment', payment_order.type + assert payment_order.paid? + end + + def test_attaches_failed_payment_order_to_invoice + assert @invoice.unpaid? + account = accounts(:cash) + account.update!(registrar: registrars(:goodnames)) + + capture_io { run_task } + @invoice.reload + + payment_order = @invoice.payment_orders.last + assert_equal 'PaymentOrders::SystemPayment', payment_order.type + assert payment_order.failed? + end + + def test_output + assert_output "Transactions processed: 1\n" do + run_task + end + end + + def test_parses_keystore_properly + assert_nothing_raised do + run_task + end + end + + private + + def run_task + Rake::Task['invoices:process_payments'].execute + end + + def create_payable_invoice(attributes = {}) + invoice = invoices(:one) + invoice.update!({ account_activity: nil, cancelled_at: nil }.merge(attributes)) + invoice + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index 92d82b86f..6e1b10c88 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,20 +1,30 @@ if ENV['COVERAGE'] require 'simplecov' - SimpleCov.command_name 'test' + SimpleCov.start 'rails' do + add_filter '/app/models/version/' + add_filter '/lib/action_controller/' + add_filter '/lib/core_monkey_patches/' + add_filter '/lib/daemons/' + add_filter '/lib/gem_monkey_patches/' + end end ENV['RAILS_ENV'] ||= 'test' -require File.expand_path('../../config/environment', __FILE__) +require_relative '../config/environment' require 'rails/test_help' require 'minitest/mock' require 'capybara/rails' require 'capybara/minitest' require 'webmock/minitest' -require 'support/rails5_assertions' # Remove once upgraded to Rails 5 -require 'support/task_test_case' +require 'support/assertions/epp_assertions' -Setting.address_processing = false -Setting.registry_country_code = 'US' + +# `bin/rails test` is not the same as `bin/rake test`. +# All tasks will be loaded (and executed) twice when using the former without `Rake::Task.clear`. +# https://github.com/rails/rails/issues/28786 +require 'rake' +Rake::Task.clear +Rails.application.load_tasks class CompanyRegisterClientStub Company = Struct.new(:registration_number) @@ -29,8 +39,6 @@ CompanyRegister::Client = CompanyRegisterClientStub EInvoice.provider = EInvoice::Providers::TestProvider.new class ActiveSupport::TestCase - include FactoryBot::Syntax::Methods - ActiveRecord::Migration.check_pending! fixtures :all set_fixture_class log_domains: DomainVersion @@ -40,13 +48,6 @@ class ActiveSupport::TestCase end end -# Allows testing OPTIONS request just like GET or POST -module ActionDispatch::Integration::RequestHelpers - def options(path, parameters = nil, headers_or_env = nil) - process :options, path, parameters, headers_or_env - end -end - class ApplicationIntegrationTest < ActionDispatch::IntegrationTest include Capybara::DSL include Capybara::Minitest::Assertions @@ -60,4 +61,6 @@ class ApplicationIntegrationTest < ActionDispatch::IntegrationTest end end -require 'application_system_test_case' +class EppTestCase < ActionDispatch::IntegrationTest + include Assertions::EppAssertions +end diff --git a/vendor/bin/wkhtmltopdf b/vendor/bin/wkhtmltopdf deleted file mode 100755 index 018966446..000000000 Binary files a/vendor/bin/wkhtmltopdf and /dev/null differ