mirror of
https://github.com/google/nomulus
synced 2026-07-07 08:36:50 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e88ff77ecb | |||
| 0781010b16 | |||
| ab4bac05d1 | |||
| 8e22ce7c70 | |||
| d96a5547ce | |||
| 05b43965d1 | |||
| 43000a5f80 | |||
| a66b9ea749 | |||
| 36a660a8ad |
+11
-18
@@ -100,12 +100,12 @@ PRESUBMITS = {
|
||||
{"node_modules/"}, REQUIRED):
|
||||
"Source files must end in a newline.",
|
||||
|
||||
# System.(out|err).println should only appear in tools/
|
||||
# System.(out|err).println should only appear in tools/ or load-testing/
|
||||
PresubmitCheck(
|
||||
r".*\bSystem\.(out|err)\.print", "java", {
|
||||
"StackdriverDashboardBuilder.java", "/tools/", "/example/",
|
||||
"RegistryTestServerMain.java", "TestServerExtension.java",
|
||||
"FlowDocumentationTool.java"
|
||||
"/load-testing/", "RegistryTestServerMain.java",
|
||||
"TestServerExtension.java", "FlowDocumentationTool.java"
|
||||
}):
|
||||
"System.(out|err).println is only allowed in tools/ packages. Please "
|
||||
"use a logger instead.",
|
||||
@@ -173,23 +173,11 @@ PRESUBMITS = {
|
||||
):
|
||||
"JavaScript files should not include console logging.",
|
||||
PresubmitCheck(
|
||||
r".*org\.testcontainers\.shaded.*",
|
||||
r".*\nimport (static )?.*\.shaded\..*",
|
||||
"java",
|
||||
{"/node_modules/"},
|
||||
):
|
||||
"Do not use shaded dependencies from testcontainers.",
|
||||
PresubmitCheck(
|
||||
r".*autovalue\.shaded.*",
|
||||
"java",
|
||||
{"/node_modules/"},
|
||||
):
|
||||
"Do not use shaded dependencies from autovalue.",
|
||||
PresubmitCheck(
|
||||
r".*avro\.shaded.*",
|
||||
"java",
|
||||
{"/node_modules/"},
|
||||
):
|
||||
"Do not use shaded dependencies from avro.",
|
||||
"Do not use shaded dependencies",
|
||||
PresubmitCheck(
|
||||
r".*com\.google\.common\.truth\.Truth8.*",
|
||||
"java",
|
||||
@@ -202,7 +190,12 @@ PRESUBMITS = {
|
||||
{"/node_modules/", "JpaTransactionManagerImpl.java"},
|
||||
):
|
||||
"Do not use java.util.Date. Use classes in java.time package instead.",
|
||||
|
||||
PresubmitCheck(
|
||||
r".*com\.google\.api\.client\.http\.HttpStatusCodes.*",
|
||||
"java",
|
||||
{"/node_modules/"},
|
||||
):
|
||||
"Use status code from jakarta.servlet.http.HttpServletResponse.",
|
||||
}
|
||||
|
||||
# Note that this regex only works for one kind of Flyway file. If we want to
|
||||
|
||||
Generated
+83
-14
@@ -18,7 +18,6 @@
|
||||
"@angular/platform-browser": "^17.3.5",
|
||||
"@angular/platform-browser-dynamic": "^17.3.5",
|
||||
"@angular/router": "^17.3.5",
|
||||
"express": "^4.16.4",
|
||||
"rxjs": "~7.5.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.14.2"
|
||||
@@ -5745,6 +5744,7 @@
|
||||
"version": "1.3.8",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
||||
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"mime-types": "~2.1.34",
|
||||
"negotiator": "0.6.3"
|
||||
@@ -5983,7 +5983,8 @@
|
||||
"node_modules/array-flatten": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
|
||||
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/array-union": {
|
||||
"version": "2.1.0",
|
||||
@@ -6253,6 +6254,7 @@
|
||||
"version": "1.20.2",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
|
||||
"integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"bytes": "3.1.2",
|
||||
"content-type": "~1.0.5",
|
||||
@@ -6276,6 +6278,7 @@
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
@@ -6283,7 +6286,8 @@
|
||||
"node_modules/body-parser/node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/bonjour-service": {
|
||||
"version": "1.2.1",
|
||||
@@ -6397,6 +6401,7 @@
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
@@ -6459,6 +6464,7 @@
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
|
||||
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
@@ -6968,6 +6974,7 @@
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
||||
"integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"safe-buffer": "5.2.1"
|
||||
},
|
||||
@@ -6979,6 +6986,7 @@
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
|
||||
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
@@ -7001,7 +7009,8 @@
|
||||
"node_modules/cookie-signature": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
|
||||
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/copy-anything": {
|
||||
"version": "2.0.6",
|
||||
@@ -7414,6 +7423,7 @@
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
||||
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
@@ -7448,6 +7458,7 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
@@ -7465,6 +7476,7 @@
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
|
||||
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.8",
|
||||
"npm": "1.2.8000 || >= 1.4.16"
|
||||
@@ -7630,7 +7642,8 @@
|
||||
"node_modules/ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
|
||||
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ejs": {
|
||||
"version": "3.1.10",
|
||||
@@ -7672,6 +7685,7 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
@@ -7822,6 +7836,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
|
||||
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"get-intrinsic": "^1.2.4"
|
||||
},
|
||||
@@ -7833,6 +7848,7 @@
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
@@ -7906,7 +7922,8 @@
|
||||
"node_modules/escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
|
||||
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
@@ -8336,6 +8353,7 @@
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
@@ -8388,6 +8406,7 @@
|
||||
"version": "4.19.2",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
|
||||
"integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"accepts": "~1.3.8",
|
||||
"array-flatten": "1.1.1",
|
||||
@@ -8429,6 +8448,7 @@
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
|
||||
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
@@ -8437,6 +8457,7 @@
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
@@ -8445,6 +8466,7 @@
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
|
||||
"integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"debug": "2.6.9",
|
||||
"encodeurl": "~1.0.2",
|
||||
@@ -8461,12 +8483,14 @@
|
||||
"node_modules/express/node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/express/node_modules/statuses": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
@@ -8787,6 +8811,7 @@
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
@@ -8808,6 +8833,7 @@
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
@@ -8874,6 +8900,7 @@
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||
"dev": true,
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
@@ -8900,6 +8927,7 @@
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
@@ -9028,6 +9056,7 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
|
||||
"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"get-intrinsic": "^1.1.3"
|
||||
},
|
||||
@@ -9066,6 +9095,7 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
||||
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"es-define-property": "^1.0.0"
|
||||
},
|
||||
@@ -9077,6 +9107,7 @@
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
|
||||
"integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
@@ -9088,6 +9119,7 @@
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
@@ -9099,6 +9131,7 @@
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
@@ -9226,6 +9259,7 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
||||
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"depd": "2.0.0",
|
||||
"inherits": "2.0.4",
|
||||
@@ -9241,6 +9275,7 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
@@ -9328,6 +9363,7 @@
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"safer-buffer": ">= 2.1.2 < 3"
|
||||
},
|
||||
@@ -9463,7 +9499,8 @@
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ini": {
|
||||
"version": "4.1.2",
|
||||
@@ -10872,6 +10909,7 @@
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
"integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
@@ -10891,7 +10929,8 @@
|
||||
"node_modules/merge-descriptors": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||
"integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
|
||||
"integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/merge-stream": {
|
||||
"version": "2.0.0",
|
||||
@@ -10912,6 +10951,7 @@
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
@@ -10957,6 +10997,7 @@
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
@@ -10965,6 +11006,7 @@
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
@@ -11325,6 +11367,7 @@
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
||||
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
@@ -11850,6 +11893,7 @@
|
||||
"version": "1.13.1",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
|
||||
"integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==",
|
||||
"dev": true,
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
@@ -11864,6 +11908,7 @@
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
|
||||
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ee-first": "1.1.1"
|
||||
},
|
||||
@@ -12238,6 +12283,7 @@
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
@@ -12303,7 +12349,8 @@
|
||||
"node_modules/path-to-regexp": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
|
||||
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/path-type": {
|
||||
"version": "4.0.0",
|
||||
@@ -12679,6 +12726,7 @@
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"forwarded": "0.2.0",
|
||||
"ipaddr.js": "1.9.1"
|
||||
@@ -12691,6 +12739,7 @@
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
@@ -12730,6 +12779,7 @@
|
||||
"version": "6.11.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
|
||||
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"side-channel": "^1.0.4"
|
||||
},
|
||||
@@ -12773,6 +12823,7 @@
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
@@ -12781,6 +12832,7 @@
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
|
||||
"integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"bytes": "3.1.2",
|
||||
"http-errors": "2.0.0",
|
||||
@@ -13189,6 +13241,7 @@
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -13207,7 +13260,8 @@
|
||||
"node_modules/safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/safevalues": {
|
||||
"version": "0.3.4",
|
||||
@@ -13353,6 +13407,7 @@
|
||||
"version": "0.18.0",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
|
||||
"integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"debug": "2.6.9",
|
||||
"depd": "2.0.0",
|
||||
@@ -13376,6 +13431,7 @@
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
@@ -13383,12 +13439,14 @@
|
||||
"node_modules/send/node_modules/debug/node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/send/node_modules/mime": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"mime": "cli.js"
|
||||
},
|
||||
@@ -13399,12 +13457,14 @@
|
||||
"node_modules/send/node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/send/node_modules/statuses": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
@@ -13491,6 +13551,7 @@
|
||||
"version": "1.15.0",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
|
||||
"integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
@@ -13505,6 +13566,7 @@
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"define-data-property": "^1.1.4",
|
||||
"es-errors": "^1.3.0",
|
||||
@@ -13520,7 +13582,8 @@
|
||||
"node_modules/setprototypeof": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
|
||||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/shallow-clone": {
|
||||
"version": "3.0.1",
|
||||
@@ -13568,6 +13631,7 @@
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
|
||||
"integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.7",
|
||||
"es-errors": "^1.3.0",
|
||||
@@ -14338,6 +14402,7 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
}
|
||||
@@ -14424,6 +14489,7 @@
|
||||
"version": "1.6.18",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"media-typer": "0.3.0",
|
||||
"mime-types": "~2.1.24"
|
||||
@@ -14566,6 +14632,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
@@ -14619,6 +14686,7 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||
"integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4.0"
|
||||
}
|
||||
@@ -14658,6 +14726,7 @@
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
import { Component, computed } from '@angular/core';
|
||||
import { RegistrarService } from '../registrar/registrar.service';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
|
||||
@Component({
|
||||
selector: 'app-billingInfo',
|
||||
@@ -22,20 +23,25 @@ import { RegistrarService } from '../registrar/registrar.service';
|
||||
})
|
||||
export class BillingInfoComponent {
|
||||
public static PATH = 'billingInfo';
|
||||
constructor(public registrarService: RegistrarService) {}
|
||||
constructor(
|
||||
public registrarService: RegistrarService,
|
||||
private _snackBar: MatSnackBar
|
||||
) {}
|
||||
|
||||
driveFolderUrl = computed<string>(() => {
|
||||
if (this.registrarService.registrar()?.driveFolderId) {
|
||||
return `https://drive.google.com/drive/folders/${
|
||||
return (
|
||||
'https://drive.google.com/drive/folders/' +
|
||||
this.registrarService.registrar()?.driveFolderId
|
||||
}`;
|
||||
);
|
||||
}
|
||||
return '';
|
||||
});
|
||||
|
||||
openBillingDetails(e: MouseEvent) {
|
||||
if (!this.driveFolderUrl()) {
|
||||
if (!this.registrarService.registrar()?.driveFolderId) {
|
||||
e.preventDefault();
|
||||
this._snackBar.open('Billing Folder ID has not been assigned');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
}
|
||||
&-driveId {
|
||||
min-width: 200px;
|
||||
word-break: break-all;
|
||||
word-break: break-word;
|
||||
}
|
||||
&-registryLockAllowed {
|
||||
max-width: 80px;
|
||||
|
||||
@@ -51,10 +51,12 @@ export const columns = [
|
||||
columnDef: 'billingAccountMap',
|
||||
header: 'Billing Accounts',
|
||||
cell: (record: Registrar) =>
|
||||
// @ts-ignore - completely legit line, but TS keeps complaining
|
||||
`${Object.entries(record.billingAccountMap).reduce((acc, [key, val]) => {
|
||||
return `${acc}${key}=${val}<br/>`;
|
||||
}, '')}`,
|
||||
`${Object.entries(record.billingAccountMap || {}).reduce(
|
||||
(acc, [key, val]) => {
|
||||
return `${acc}${key}=${val}<br/>`;
|
||||
},
|
||||
''
|
||||
)}`,
|
||||
},
|
||||
{
|
||||
columnDef: 'registryLockAllowed',
|
||||
|
||||
@@ -71,7 +71,7 @@ export default class ContactComponent {
|
||||
effect(() => {
|
||||
if (this.contactService.contacts()) {
|
||||
this.dataSource = new MatTableDataSource<ViewReadyContact>(
|
||||
this.contactService.contacts().map(contactTypeToViewReadyContact)
|
||||
this.contactService.contacts()
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -37,7 +37,7 @@ export default class WhoisComponent {
|
||||
result += `${registrar?.localizedAddress?.state} `;
|
||||
}
|
||||
if (registrar?.localizedAddress?.countryCode) {
|
||||
result += registrar?.localizedAddress?.countryCode;
|
||||
result += `${registrar?.localizedAddress?.countryCode} `;
|
||||
}
|
||||
if (registrar?.localizedAddress?.zip) {
|
||||
result += registrar?.localizedAddress?.zip;
|
||||
|
||||
@@ -63,7 +63,7 @@ body {
|
||||
.console-app__list-value {
|
||||
font-size: 14px;
|
||||
white-space: pre-line;
|
||||
word-break: break-all;
|
||||
word-break: break-word;
|
||||
color: var(--text);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,9 +23,9 @@ import static google.registry.model.tld.label.ReservedList.loadReservedLists;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.replicaTm;
|
||||
import static google.registry.request.Action.Method.GET;
|
||||
import static google.registry.request.Action.Method.POST;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
|
||||
import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.cloud.storage.BlobId;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
@@ -190,7 +190,7 @@ public class UploadBsaUnavailableDomainsAction implements Runnable {
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
logger.atSevere().withCause(e).log("Error while attempting to upload to BSA, aborting.");
|
||||
response.setStatus(HttpStatusCodes.STATUS_CODE_SERVER_ERROR);
|
||||
response.setStatus(SC_INTERNAL_SERVER_ERROR);
|
||||
response.setPayload("Error while attempting to upload to BSA: " + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
|
||||
package google.registry.rdap;
|
||||
|
||||
import static com.google.api.client.http.HttpStatusCodes.STATUS_CODE_OK;
|
||||
import static com.google.common.net.HttpHeaders.ACCEPT_ENCODING;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.request.UrlConnectionUtils.gUnzipBytes;
|
||||
import static google.registry.request.UrlConnectionUtils.isGZipped;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
@@ -114,7 +114,7 @@ public final class UpdateRegistrarRdapBaseUrlsAction implements Runnable {
|
||||
connection.setRequestProperty(ACCEPT_ENCODING, "gzip");
|
||||
String csvString;
|
||||
try {
|
||||
if (connection.getResponseCode() != STATUS_CODE_OK) {
|
||||
if (connection.getResponseCode() != SC_OK) {
|
||||
throw new UrlConnectionException("Failed to load RDAP base URLs from ICANN", connection);
|
||||
}
|
||||
// With GZIP encoding header in the request (see above) ICANN had still sent response in plain
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
|
||||
package google.registry.rde;
|
||||
|
||||
import static com.google.api.client.http.HttpStatusCodes.STATUS_CODE_BAD_REQUEST;
|
||||
import static com.google.api.client.http.HttpStatusCodes.STATUS_CODE_OK;
|
||||
import static google.registry.request.UrlConnectionUtils.getResponseBytes;
|
||||
import static google.registry.request.UrlConnectionUtils.setBasicAuth;
|
||||
import static google.registry.request.UrlConnectionUtils.setPayload;
|
||||
import static google.registry.util.DomainNameUtils.canonicalizeHostname;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.google.api.client.http.HttpMethods;
|
||||
@@ -85,7 +85,7 @@ public class RdeReporter {
|
||||
|
||||
try {
|
||||
responseCode = connection.getResponseCode();
|
||||
if (responseCode != STATUS_CODE_OK && responseCode != STATUS_CODE_BAD_REQUEST) {
|
||||
if (responseCode != SC_OK && responseCode != SC_BAD_REQUEST) {
|
||||
logger.atWarning().log("Connection to RDE report server failed: %d", responseCode);
|
||||
throw new UrlConnectionException("PUT failed", connection);
|
||||
}
|
||||
@@ -96,7 +96,7 @@ public class RdeReporter {
|
||||
|
||||
// We know that an HTTP 200 response can only contain a result code of
|
||||
// 1000 (i. e. success), there is no need to parse it.
|
||||
if (responseCode != STATUS_CODE_OK) {
|
||||
if (responseCode != SC_OK) {
|
||||
XjcIirdeaResult result = parseResult(responseBytes);
|
||||
logger.atWarning().log(
|
||||
"Rejected when trying to PUT RDE report to ICANN server: %d %s\n%s",
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
|
||||
package google.registry.reporting.icann;
|
||||
|
||||
import static com.google.api.client.http.HttpStatusCodes.STATUS_CODE_OK;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.net.MediaType.CSV_UTF_8;
|
||||
import static google.registry.model.tld.Tlds.assertTldExists;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
|
||||
import com.google.api.client.http.HttpMethods;
|
||||
import com.google.common.base.Ascii;
|
||||
@@ -95,7 +95,7 @@ public class IcannHttpReporter {
|
||||
try {
|
||||
responseCode = connection.getResponseCode();
|
||||
content = UrlConnectionUtils.getResponseBytes(connection);
|
||||
if (responseCode != STATUS_CODE_OK) {
|
||||
if (responseCode != SC_OK) {
|
||||
XjcIirdeaResult result = parseResult(content);
|
||||
logger.atWarning().log(
|
||||
"PUT rejected, status code %s:\n%s\n%s",
|
||||
|
||||
@@ -15,10 +15,17 @@
|
||||
package google.registry.ui.server.console;
|
||||
|
||||
import static google.registry.request.Action.Method.GET;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_FORBIDDEN;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import google.registry.model.console.ConsolePermission;
|
||||
import google.registry.model.console.GlobalRole;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.request.HttpException;
|
||||
import google.registry.request.auth.AuthResult;
|
||||
import google.registry.security.XsrfTokenManager;
|
||||
import google.registry.ui.server.registrar.ConsoleApiParams;
|
||||
@@ -31,6 +38,9 @@ import java.util.Optional;
|
||||
|
||||
/** Base class for handling Console API requests */
|
||||
public abstract class ConsoleApiAction implements Runnable {
|
||||
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
|
||||
protected ConsoleApiParams consoleApiParams;
|
||||
|
||||
public ConsoleApiAction(ConsoleApiParams consoleApiParams) {
|
||||
@@ -43,7 +53,7 @@ public abstract class ConsoleApiAction implements Runnable {
|
||||
AuthResult authResult = consoleApiParams.authResult();
|
||||
if (authResult.userAuthInfo().isEmpty()
|
||||
|| authResult.userAuthInfo().get().consoleUser().isEmpty()) {
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_UNAUTHORIZED);
|
||||
consoleApiParams.response().setStatus(SC_UNAUTHORIZED);
|
||||
return;
|
||||
}
|
||||
User user = consoleApiParams.authResult().userAuthInfo().get().consoleUser().get();
|
||||
@@ -60,15 +70,34 @@ public abstract class ConsoleApiAction implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
if (consoleApiParams.request().getMethod().equals(GET.toString())) {
|
||||
getHandler(user);
|
||||
} else {
|
||||
if (verifyXSRF()) {
|
||||
postHandler(user);
|
||||
try {
|
||||
if (consoleApiParams.request().getMethod().equals(GET.toString())) {
|
||||
getHandler(user);
|
||||
} else {
|
||||
if (verifyXSRF()) {
|
||||
postHandler(user);
|
||||
}
|
||||
}
|
||||
} catch (ConsolePermissionForbiddenException e) {
|
||||
logger.atWarning().withCause(e).log("Forbidden");
|
||||
setFailedResponse("", SC_FORBIDDEN);
|
||||
} catch (HttpException.BadRequestException | IllegalArgumentException e) {
|
||||
logger.atWarning().withCause(e).log("Error in request");
|
||||
setFailedResponse(Throwables.getRootCause(e).getMessage(), SC_BAD_REQUEST);
|
||||
} catch (Throwable t) {
|
||||
logger.atWarning().withCause(t).log("Internal server error");
|
||||
setFailedResponse(Throwables.getRootCause(t).getMessage(), SC_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkPermission(User user, String registrarId, ConsolePermission permission) {
|
||||
if (!user.getUserRoles().hasPermission(registrarId, permission)) {
|
||||
throw new ConsolePermissionForbiddenException(
|
||||
String.format(
|
||||
"User %s does not have permission %s on registrar %s",
|
||||
user.getEmailAddress(), permission, registrarId));
|
||||
}
|
||||
}
|
||||
|
||||
protected void postHandler(User user) {
|
||||
throw new UnsupportedOperationException("Console API POST handler not implemented");
|
||||
@@ -90,10 +119,16 @@ public abstract class ConsoleApiAction implements Runnable {
|
||||
.findFirst();
|
||||
if (maybeCookie.isEmpty()
|
||||
|| !consoleApiParams.xsrfTokenManager().validateToken(maybeCookie.get().getValue())) {
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_UNAUTHORIZED);
|
||||
consoleApiParams.response().setStatus(SC_UNAUTHORIZED);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Specialized exception class used for failure when a user doesn't have the right permission. */
|
||||
private static class ConsolePermissionForbiddenException extends RuntimeException {
|
||||
private ConsolePermissionForbiddenException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
package google.registry.ui.server.console;
|
||||
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_NOT_FOUND;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.gson.Gson;
|
||||
import google.registry.model.EppResourceUtils;
|
||||
import google.registry.model.console.ConsolePermission;
|
||||
@@ -59,16 +60,16 @@ public class ConsoleDomainGetAction extends ConsoleApiAction {
|
||||
EppResourceUtils.loadByForeignKeyCached(
|
||||
Domain.class, paramDomain, tm().getTransactionTime()));
|
||||
if (possibleDomain.isEmpty()) {
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_NOT_FOUND);
|
||||
consoleApiParams.response().setStatus(SC_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
Domain domain = possibleDomain.get();
|
||||
if (!user.getUserRoles()
|
||||
.hasPermission(domain.getCurrentSponsorRegistrarId(), ConsolePermission.DOWNLOAD_DOMAINS)) {
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_NOT_FOUND);
|
||||
consoleApiParams.response().setStatus(SC_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
||||
consoleApiParams.response().setStatus(SC_OK);
|
||||
consoleApiParams.response().setPayload(gson.toJson(domain));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,10 +14,11 @@
|
||||
|
||||
package google.registry.ui.server.console;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static google.registry.model.console.ConsolePermission.DOWNLOAD_DOMAINS;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Ascii;
|
||||
import com.google.gson.Gson;
|
||||
@@ -82,22 +83,11 @@ public class ConsoleDomainListAction extends ConsoleApiAction {
|
||||
|
||||
@Override
|
||||
protected void getHandler(User user) {
|
||||
if (!user.getUserRoles().hasPermission(registrarId, DOWNLOAD_DOMAINS)) {
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
if (resultsPerPage < 1 || resultsPerPage > 500) {
|
||||
setFailedResponse(
|
||||
"Results per page must be between 1 and 500 inclusive",
|
||||
HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
if (pageNumber < 0) {
|
||||
setFailedResponse(
|
||||
"Page number must be non-negative", HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
|
||||
checkPermission(user, registrarId, DOWNLOAD_DOMAINS);
|
||||
checkArgument(
|
||||
resultsPerPage > 0 && resultsPerPage <= 500,
|
||||
"Results per page must be between 1 and 500 inclusive");
|
||||
checkArgument(pageNumber >= 0, "Page number must be non-negative");
|
||||
tm().transact(this::runInTransaction);
|
||||
}
|
||||
|
||||
@@ -128,7 +118,7 @@ public class ConsoleDomainListAction extends ConsoleApiAction {
|
||||
consoleApiParams
|
||||
.response()
|
||||
.setPayload(gson.toJson(new DomainListResult(domains, checkpoint, actualTotalResults)));
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
||||
consoleApiParams.response().setStatus(SC_OK);
|
||||
}
|
||||
|
||||
/** Creates the query to get the total number of matching domains, interpolating as necessary. */
|
||||
|
||||
@@ -58,7 +58,7 @@ public class ConsoleDumDownloadAction extends ConsoleApiAction {
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
|
||||
public static final String PATH = "/console-api/dum-download";
|
||||
private Clock clock;
|
||||
private final Clock clock;
|
||||
private final String registrarId;
|
||||
private final String dumFileName;
|
||||
|
||||
@@ -76,11 +76,7 @@ public class ConsoleDumDownloadAction extends ConsoleApiAction {
|
||||
|
||||
@Override
|
||||
protected void getHandler(User user) {
|
||||
if (!user.getUserRoles().hasPermission(registrarId, ConsolePermission.DOWNLOAD_DOMAINS)) {
|
||||
consoleApiParams.response().setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
|
||||
checkPermission(user, registrarId, ConsolePermission.DOWNLOAD_DOMAINS);
|
||||
consoleApiParams.response().setContentType(MediaType.CSV_UTF_8);
|
||||
consoleApiParams
|
||||
.response()
|
||||
|
||||
+48
-48
@@ -14,20 +14,22 @@
|
||||
|
||||
package google.registry.ui.server.console;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.request.Action.Method.POST;
|
||||
import static google.registry.request.RequestParameters.extractRequiredParameter;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_FORBIDDEN;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_NOT_FOUND;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import google.registry.flows.EppException.AuthenticationErrorException;
|
||||
import google.registry.flows.PasswordOnlyTransportCredentials;
|
||||
import google.registry.groups.GmailClient;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.request.Action;
|
||||
import google.registry.request.HttpException.BadRequestException;
|
||||
import google.registry.request.Parameter;
|
||||
import google.registry.request.auth.Auth;
|
||||
import google.registry.request.auth.AuthenticatedRegistrarAccessor;
|
||||
import google.registry.request.auth.AuthenticatedRegistrarAccessor.RegistrarAccessDeniedException;
|
||||
@@ -43,9 +45,6 @@ import javax.mail.internet.InternetAddress;
|
||||
method = {POST},
|
||||
auth = Auth.AUTH_PUBLIC_LOGGED_IN)
|
||||
public class ConsoleEppPasswordAction extends ConsoleApiAction {
|
||||
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
|
||||
protected static final String EMAIL_SUBJ = "EPP password update confirmation";
|
||||
protected static final String EMAIL_BODY =
|
||||
"Dear %s,\n" + "This is to confirm that your account password has been changed.";
|
||||
@@ -57,70 +56,71 @@ public class ConsoleEppPasswordAction extends ConsoleApiAction {
|
||||
private final AuthenticatedRegistrarAccessor registrarAccessor;
|
||||
private final GmailClient gmailClient;
|
||||
|
||||
private final Optional<EppPasswordData> eppPasswordChangeRequest;
|
||||
|
||||
@Inject
|
||||
public ConsoleEppPasswordAction(
|
||||
ConsoleApiParams consoleApiParams,
|
||||
AuthenticatedRegistrarAccessor registrarAccessor,
|
||||
GmailClient gmailClient) {
|
||||
GmailClient gmailClient,
|
||||
@Parameter("eppPasswordChangeRequest") Optional<EppPasswordData> eppPasswordChangeRequest) {
|
||||
super(consoleApiParams);
|
||||
this.registrarAccessor = registrarAccessor;
|
||||
this.gmailClient = gmailClient;
|
||||
this.eppPasswordChangeRequest = eppPasswordChangeRequest;
|
||||
}
|
||||
|
||||
private void confirmParamsAvailable() {
|
||||
checkArgument(this.eppPasswordChangeRequest.isPresent(), "Epp Password update body is invalid");
|
||||
var eppRequestBody = this.eppPasswordChangeRequest.get();
|
||||
var errorMsg = "Missing param(s): %s";
|
||||
checkArgument(!Strings.isNullOrEmpty(eppRequestBody.registrarId()), errorMsg, "registrarId");
|
||||
checkArgument(!Strings.isNullOrEmpty(eppRequestBody.oldPassword()), errorMsg, "oldPassword");
|
||||
checkArgument(!Strings.isNullOrEmpty(eppRequestBody.newPassword()), errorMsg, "newPassword");
|
||||
checkArgument(
|
||||
!Strings.isNullOrEmpty(eppRequestBody.newPasswordRepeat()), errorMsg, "newPasswordRepeat");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postHandler(User user) {
|
||||
String registrarId;
|
||||
String oldPassword;
|
||||
String newPassword;
|
||||
String newPasswordRepeat;
|
||||
this.confirmParamsAvailable();
|
||||
|
||||
try {
|
||||
registrarId = extractRequiredParameter(consoleApiParams.request(), "registrarId");
|
||||
oldPassword = extractRequiredParameter(consoleApiParams.request(), "oldPassword");
|
||||
newPassword = extractRequiredParameter(consoleApiParams.request(), "newPassword");
|
||||
newPasswordRepeat = extractRequiredParameter(consoleApiParams.request(), "newPasswordRepeat");
|
||||
} catch (BadRequestException e) {
|
||||
setFailedResponse(e.getMessage(), HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!newPassword.equals(newPasswordRepeat)) {
|
||||
setFailedResponse("New password fields don't match", HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
var eppRequestBody = this.eppPasswordChangeRequest.get();
|
||||
checkArgument(
|
||||
eppRequestBody.newPassword().equals(eppRequestBody.newPasswordRepeat()),
|
||||
"New password fields don't match");
|
||||
|
||||
Registrar registrar;
|
||||
try {
|
||||
registrar = registrarAccessor.getRegistrar(registrarId);
|
||||
registrar = registrarAccessor.getRegistrar(eppRequestBody.registrarId());
|
||||
} catch (RegistrarAccessDeniedException e) {
|
||||
setFailedResponse(e.getMessage(), HttpStatusCodes.STATUS_CODE_NOT_FOUND);
|
||||
setFailedResponse(e.getMessage(), SC_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
credentials.validate(registrar, oldPassword);
|
||||
credentials.validate(registrar, eppRequestBody.oldPassword());
|
||||
} catch (AuthenticationErrorException e) {
|
||||
setFailedResponse(e.getMessage(), HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
setFailedResponse(e.getMessage(), SC_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
tm().transact(
|
||||
() -> {
|
||||
tm().put(registrar.asBuilder().setPassword(newPassword).build());
|
||||
this.gmailClient.sendEmail(
|
||||
EmailMessage.create(
|
||||
EMAIL_SUBJ,
|
||||
String.format(EMAIL_BODY, registrar.getRegistrarName()),
|
||||
new InternetAddress(registrar.getEmailAddress(), true)));
|
||||
});
|
||||
} catch (Throwable e) {
|
||||
logger.atWarning().withCause(e).log("Failed to update password.");
|
||||
String message =
|
||||
Optional.ofNullable(Throwables.getRootCause(e).getMessage()).orElse("Unspecified error");
|
||||
setFailedResponse(message, HttpStatusCodes.STATUS_CODE_SERVER_ERROR);
|
||||
}
|
||||
tm().transact(
|
||||
() -> {
|
||||
tm().put(registrar.asBuilder().setPassword(eppRequestBody.newPassword()).build());
|
||||
this.gmailClient.sendEmail(
|
||||
EmailMessage.create(
|
||||
EMAIL_SUBJ,
|
||||
String.format(EMAIL_BODY, registrar.getRegistrarName()),
|
||||
new InternetAddress(registrar.getEmailAddress(), true)));
|
||||
});
|
||||
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
||||
consoleApiParams.response().setStatus(SC_OK);
|
||||
}
|
||||
|
||||
public record EppPasswordData(
|
||||
@Expose String registrarId,
|
||||
@Expose String oldPassword,
|
||||
@Expose String newPassword,
|
||||
@Expose String newPasswordRepeat) {}
|
||||
}
|
||||
|
||||
+36
-71
@@ -14,6 +14,7 @@
|
||||
|
||||
package google.registry.ui.server.console;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.request.Action.Method.GET;
|
||||
@@ -23,10 +24,10 @@ import static google.registry.request.RequestParameters.extractOptionalLongParam
|
||||
import static google.registry.request.RequestParameters.extractOptionalParameter;
|
||||
import static google.registry.request.RequestParameters.extractRequiredParameter;
|
||||
import static google.registry.ui.server.registrar.RegistryLockPostAction.VERIFICATION_EMAIL_TEMPLATE;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.google.gson.Gson;
|
||||
import google.registry.flows.EppException;
|
||||
import google.registry.flows.domain.DomainFlowUtils;
|
||||
@@ -37,7 +38,6 @@ import google.registry.model.domain.RegistryLock;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.model.tld.RegistryLockDao;
|
||||
import google.registry.request.Action;
|
||||
import google.registry.request.HttpException;
|
||||
import google.registry.request.Parameter;
|
||||
import google.registry.request.Response;
|
||||
import google.registry.request.auth.Auth;
|
||||
@@ -66,8 +66,6 @@ import org.joda.time.Duration;
|
||||
auth = Auth.AUTH_PUBLIC_LOGGED_IN)
|
||||
public class ConsoleRegistryLockAction extends ConsoleApiAction {
|
||||
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
|
||||
static final String PATH = "/console-api/registry-lock";
|
||||
|
||||
private final DomainLockUtils domainLockUtils;
|
||||
@@ -91,12 +89,9 @@ public class ConsoleRegistryLockAction extends ConsoleApiAction {
|
||||
|
||||
@Override
|
||||
protected void getHandler(User user) {
|
||||
if (!user.getUserRoles().hasPermission(registrarId, ConsolePermission.REGISTRY_LOCK)) {
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
checkPermission(user, registrarId, ConsolePermission.REGISTRY_LOCK);
|
||||
consoleApiParams.response().setPayload(gson.toJson(getLockedDomains()));
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
||||
consoleApiParams.response().setStatus(SC_OK);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -104,85 +99,55 @@ public class ConsoleRegistryLockAction extends ConsoleApiAction {
|
||||
HttpServletRequest req = consoleApiParams.request();
|
||||
Response response = consoleApiParams.response();
|
||||
// User must have the proper permission on the registrar
|
||||
if (!user.getUserRoles().hasPermission(registrarId, ConsolePermission.REGISTRY_LOCK)) {
|
||||
setFailedResponse("", HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
checkPermission(user, registrarId, ConsolePermission.REGISTRY_LOCK);
|
||||
|
||||
// Shouldn't happen, but double-check the registrar has registry lock enabled
|
||||
Registrar registrar = Registrar.loadByRegistrarIdCached(registrarId).get();
|
||||
if (!registrar.isRegistryLockAllowed()) {
|
||||
setFailedResponse(
|
||||
String.format("Registry lock not allowed for registrar %s", registrarId),
|
||||
HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
checkArgument(
|
||||
registrar.isRegistryLockAllowed(),
|
||||
"Registry lock not allowed for registrar %s",
|
||||
registrarId);
|
||||
|
||||
// Retrieve and validate the necessary params
|
||||
String domainName;
|
||||
boolean isLock;
|
||||
Optional<String> maybePassword;
|
||||
Optional<Long> relockDurationMillis;
|
||||
String domainName = extractRequiredParameter(req, "domainName");
|
||||
boolean isLock = extractBooleanParameter(req, "isLock");
|
||||
Optional<String> maybePassword = extractOptionalParameter(req, "password");
|
||||
Optional<Long> relockDurationMillis = extractOptionalLongParameter(req, "relockDurationMillis");
|
||||
|
||||
try {
|
||||
domainName = extractRequiredParameter(req, "domainName");
|
||||
isLock = extractBooleanParameter(req, "isLock");
|
||||
maybePassword = extractOptionalParameter(req, "password");
|
||||
relockDurationMillis = extractOptionalLongParameter(req, "relockDurationMillis");
|
||||
DomainFlowUtils.validateDomainName(domainName);
|
||||
} catch (HttpException.BadRequestException | EppException e) {
|
||||
logger.atWarning().withCause(e).log("Bad request when attempting registry lock/unlock");
|
||||
setFailedResponse(e.getMessage(), HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
return;
|
||||
} catch (EppException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
|
||||
// Passwords aren't required for admin users, otherwise we need to validate it
|
||||
boolean isAdmin = user.getUserRoles().isAdmin();
|
||||
if (!isAdmin) {
|
||||
if (maybePassword.isEmpty()) {
|
||||
setFailedResponse("No password provided", HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
checkArgument(maybePassword.isPresent(), "No password provided");
|
||||
if (!user.verifyRegistryLockPassword(maybePassword.get())) {
|
||||
setFailedResponse(
|
||||
"Incorrect registry lock password", HttpStatusCodes.STATUS_CODE_UNAUTHORIZED);
|
||||
setFailedResponse("Incorrect registry lock password", SC_UNAUTHORIZED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Optional<String> maybeRegistryLockEmail = user.getRegistryLockEmailAddress();
|
||||
if (maybeRegistryLockEmail.isEmpty()) {
|
||||
setFailedResponse(
|
||||
"User has no registry lock email address", HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
String registryLockEmail = maybeRegistryLockEmail.get();
|
||||
|
||||
try {
|
||||
tm().transact(
|
||||
() -> {
|
||||
RegistryLock registryLock =
|
||||
isLock
|
||||
? domainLockUtils.saveNewRegistryLockRequest(
|
||||
domainName, registrarId, registryLockEmail, isAdmin)
|
||||
: domainLockUtils.saveNewRegistryUnlockRequest(
|
||||
domainName,
|
||||
registrarId,
|
||||
isAdmin,
|
||||
relockDurationMillis.map(Duration::new));
|
||||
sendVerificationEmail(registryLock, registryLockEmail, isLock);
|
||||
});
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Catch IllegalArgumentExceptions separately to give a nicer error message and code
|
||||
logger.atWarning().withCause(e).log("Failed to lock/unlock domain");
|
||||
setFailedResponse(e.getMessage(), HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
return;
|
||||
} catch (Throwable t) {
|
||||
logger.atWarning().withCause(t).log("Failed to lock/unlock domain");
|
||||
setFailedResponse("Internal server error", HttpStatusCodes.STATUS_CODE_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
response.setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
||||
String registryLockEmail =
|
||||
user.getRegistryLockEmailAddress()
|
||||
.orElseThrow(
|
||||
() -> new IllegalArgumentException("User has no registry lock email address"));
|
||||
tm().transact(
|
||||
() -> {
|
||||
RegistryLock registryLock =
|
||||
isLock
|
||||
? domainLockUtils.saveNewRegistryLockRequest(
|
||||
domainName, registrarId, registryLockEmail, isAdmin)
|
||||
: domainLockUtils.saveNewRegistryUnlockRequest(
|
||||
domainName,
|
||||
registrarId,
|
||||
isAdmin,
|
||||
relockDurationMillis.map(Duration::new));
|
||||
sendVerificationEmail(registryLock, registryLockEmail, isLock);
|
||||
});
|
||||
response.setStatus(SC_OK);
|
||||
}
|
||||
|
||||
private void sendVerificationEmail(RegistryLock lock, String userEmail, boolean isLock) {
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
package google.registry.ui.server.console;
|
||||
|
||||
import static google.registry.request.Action.Method.GET;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import google.registry.config.RegistryConfig.Config;
|
||||
import google.registry.model.console.User;
|
||||
@@ -88,6 +88,6 @@ public class ConsoleUserDataAction extends ConsoleApiAction {
|
||||
"technicalDocsUrl", technicalDocsUrl));
|
||||
|
||||
consoleApiParams.response().setPayload(json.toString());
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
||||
consoleApiParams.response().setStatus(SC_OK);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,14 +19,16 @@ import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.request.Action.Method.GET;
|
||||
import static google.registry.request.Action.Method.POST;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_FORBIDDEN;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Streams;
|
||||
import com.google.gson.Gson;
|
||||
import google.registry.model.console.ConsolePermission;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.model.registrar.RegistrarBase;
|
||||
import google.registry.model.registrar.RegistrarBase.State;
|
||||
import google.registry.model.registrar.RegistrarPoc;
|
||||
import google.registry.request.Action;
|
||||
@@ -46,11 +48,13 @@ import javax.inject.Named;
|
||||
public class RegistrarsAction extends ConsoleApiAction {
|
||||
private static final int PASSWORD_LENGTH = 16;
|
||||
private static final int PASSCODE_LENGTH = 5;
|
||||
private static final ImmutableList<RegistrarBase.Type> allowedRegistrarTypes =
|
||||
ImmutableList.of(Registrar.Type.REAL, RegistrarBase.Type.OTE);
|
||||
static final String PATH = "/console-api/registrars";
|
||||
private final Gson gson;
|
||||
private Optional<Registrar> registrar;
|
||||
private StringGenerator passwordGenerator;
|
||||
private StringGenerator passcodeGenerator;
|
||||
private final Optional<Registrar> registrar;
|
||||
private final StringGenerator passwordGenerator;
|
||||
private final StringGenerator passcodeGenerator;
|
||||
|
||||
@Inject
|
||||
public RegistrarsAction(
|
||||
@@ -69,92 +73,82 @@ public class RegistrarsAction extends ConsoleApiAction {
|
||||
@Override
|
||||
protected void getHandler(User user) {
|
||||
if (!user.getUserRoles().hasGlobalPermission(ConsolePermission.VIEW_REGISTRARS)) {
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
consoleApiParams.response().setStatus(SC_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
|
||||
ImmutableList<Registrar> registrars =
|
||||
Streams.stream(Registrar.loadAll())
|
||||
.filter(r -> r.getType() == Registrar.Type.REAL)
|
||||
.filter(r -> allowedRegistrarTypes.contains(r.getType()))
|
||||
.collect(ImmutableList.toImmutableList());
|
||||
|
||||
consoleApiParams.response().setPayload(gson.toJson(registrars));
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
||||
consoleApiParams.response().setStatus(SC_OK);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postHandler(User user) {
|
||||
if (!user.getUserRoles().isAdmin()) {
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
consoleApiParams.response().setStatus(SC_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
|
||||
if (registrar.isEmpty()) {
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
consoleApiParams.response().setPayload(gson.toJson("'registrar' parameter is not present"));
|
||||
return;
|
||||
}
|
||||
|
||||
Registrar registrarParam = registrar.get();
|
||||
Registrar registrarParam =
|
||||
registrar.orElseThrow(
|
||||
() -> new IllegalArgumentException("'registrar' parameter is not present"));
|
||||
String errorMsg = "Missing value for %s";
|
||||
try {
|
||||
checkArgument(!isNullOrEmpty(registrarParam.getRegistrarId()), errorMsg, "registrarId");
|
||||
checkArgument(!isNullOrEmpty(registrarParam.getRegistrarName()), errorMsg, "name");
|
||||
checkArgument(!registrarParam.getBillingAccountMap().isEmpty(), errorMsg, "billingAccount");
|
||||
checkArgument(registrarParam.getIanaIdentifier() != null, String.format(errorMsg, "ianaId"));
|
||||
checkArgument(
|
||||
!isNullOrEmpty(registrarParam.getIcannReferralEmail()), errorMsg, "referralEmail");
|
||||
checkArgument(!isNullOrEmpty(registrarParam.getDriveFolderId()), errorMsg, "driveId");
|
||||
checkArgument(!isNullOrEmpty(registrarParam.getEmailAddress()), errorMsg, "consoleUserEmail");
|
||||
checkArgument(
|
||||
registrarParam.getLocalizedAddress() != null
|
||||
&& !isNullOrEmpty(registrarParam.getLocalizedAddress().getState())
|
||||
&& !isNullOrEmpty(registrarParam.getLocalizedAddress().getCity())
|
||||
&& !isNullOrEmpty(registrarParam.getLocalizedAddress().getZip())
|
||||
&& !isNullOrEmpty(registrarParam.getLocalizedAddress().getCountryCode())
|
||||
&& !registrarParam.getLocalizedAddress().getStreet().isEmpty(),
|
||||
errorMsg,
|
||||
"address");
|
||||
checkArgument(!isNullOrEmpty(registrarParam.getRegistrarId()), errorMsg, "registrarId");
|
||||
checkArgument(!isNullOrEmpty(registrarParam.getRegistrarName()), errorMsg, "name");
|
||||
checkArgument(!registrarParam.getBillingAccountMap().isEmpty(), errorMsg, "billingAccount");
|
||||
checkArgument(registrarParam.getIanaIdentifier() != null, String.format(errorMsg, "ianaId"));
|
||||
checkArgument(
|
||||
!isNullOrEmpty(registrarParam.getIcannReferralEmail()), errorMsg, "referralEmail");
|
||||
checkArgument(!isNullOrEmpty(registrarParam.getDriveFolderId()), errorMsg, "driveId");
|
||||
checkArgument(!isNullOrEmpty(registrarParam.getEmailAddress()), errorMsg, "consoleUserEmail");
|
||||
checkArgument(
|
||||
registrarParam.getLocalizedAddress() != null
|
||||
&& !isNullOrEmpty(registrarParam.getLocalizedAddress().getState())
|
||||
&& !isNullOrEmpty(registrarParam.getLocalizedAddress().getCity())
|
||||
&& !isNullOrEmpty(registrarParam.getLocalizedAddress().getZip())
|
||||
&& !isNullOrEmpty(registrarParam.getLocalizedAddress().getCountryCode())
|
||||
&& !registrarParam.getLocalizedAddress().getStreet().isEmpty(),
|
||||
errorMsg,
|
||||
"address");
|
||||
|
||||
String password = passwordGenerator.createString(PASSWORD_LENGTH);
|
||||
String phonePasscode = passcodeGenerator.createString(PASSCODE_LENGTH);
|
||||
String password = passwordGenerator.createString(PASSWORD_LENGTH);
|
||||
String phonePasscode = passcodeGenerator.createString(PASSCODE_LENGTH);
|
||||
|
||||
Registrar registrar =
|
||||
new Registrar.Builder()
|
||||
.setRegistrarId(registrarParam.getRegistrarId())
|
||||
.setRegistrarName(registrarParam.getRegistrarName())
|
||||
.setBillingAccountMap(registrarParam.getBillingAccountMap())
|
||||
.setIanaIdentifier(Long.valueOf(registrarParam.getIanaIdentifier()))
|
||||
.setIcannReferralEmail(registrarParam.getIcannReferralEmail())
|
||||
.setEmailAddress(registrarParam.getIcannReferralEmail())
|
||||
.setDriveFolderId(registrarParam.getDriveFolderId())
|
||||
.setType(Registrar.Type.REAL)
|
||||
.setPassword(password)
|
||||
.setPhonePasscode(phonePasscode)
|
||||
.setState(State.PENDING)
|
||||
.setLocalizedAddress(registrarParam.getLocalizedAddress())
|
||||
.build();
|
||||
Registrar registrar =
|
||||
new Registrar.Builder()
|
||||
.setRegistrarId(registrarParam.getRegistrarId())
|
||||
.setRegistrarName(registrarParam.getRegistrarName())
|
||||
.setBillingAccountMap(registrarParam.getBillingAccountMap())
|
||||
.setIanaIdentifier(registrarParam.getIanaIdentifier())
|
||||
.setIcannReferralEmail(registrarParam.getIcannReferralEmail())
|
||||
.setEmailAddress(registrarParam.getIcannReferralEmail())
|
||||
.setDriveFolderId(registrarParam.getDriveFolderId())
|
||||
.setType(Registrar.Type.REAL)
|
||||
.setPassword(password)
|
||||
.setPhonePasscode(phonePasscode)
|
||||
.setState(State.PENDING)
|
||||
.setLocalizedAddress(registrarParam.getLocalizedAddress())
|
||||
.build();
|
||||
|
||||
RegistrarPoc contact =
|
||||
new RegistrarPoc.Builder()
|
||||
.setRegistrar(registrar)
|
||||
.setName(registrarParam.getEmailAddress())
|
||||
.setEmailAddress(registrarParam.getEmailAddress())
|
||||
.setLoginEmailAddress(registrarParam.getEmailAddress())
|
||||
.build();
|
||||
RegistrarPoc contact =
|
||||
new RegistrarPoc.Builder()
|
||||
.setRegistrar(registrar)
|
||||
.setName(registrarParam.getEmailAddress())
|
||||
.setEmailAddress(registrarParam.getEmailAddress())
|
||||
.setLoginEmailAddress(registrarParam.getEmailAddress())
|
||||
.build();
|
||||
|
||||
tm().transact(
|
||||
() -> {
|
||||
checkArgument(
|
||||
Registrar.loadByRegistrarId(registrar.getRegistrarId()).isEmpty(),
|
||||
"Registrar with registrarId %s already exists",
|
||||
registrar.getRegistrarId());
|
||||
tm().putAll(registrar, contact);
|
||||
});
|
||||
|
||||
} catch (IllegalArgumentException e) {
|
||||
setFailedResponse(e.getMessage(), HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
} catch (Throwable e) {
|
||||
setFailedResponse(e.getMessage(), HttpStatusCodes.STATUS_CODE_SERVER_ERROR);
|
||||
}
|
||||
tm().transact(
|
||||
() -> {
|
||||
checkArgument(
|
||||
Registrar.loadByRegistrarId(registrar.getRegistrarId()).isEmpty(),
|
||||
"Registrar with registrarId %s already exists",
|
||||
registrar.getRegistrarId());
|
||||
tm().putAll(registrar, contact);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,12 +14,13 @@
|
||||
|
||||
package google.registry.ui.server.console.settings;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.request.Action.Method.GET;
|
||||
import static google.registry.request.Action.Method.POST;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
@@ -66,11 +67,7 @@ public class ContactAction extends ConsoleApiAction {
|
||||
|
||||
@Override
|
||||
protected void getHandler(User user) {
|
||||
if (!user.getUserRoles().hasPermission(registrarId, ConsolePermission.VIEW_REGISTRAR_DETAILS)) {
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
|
||||
checkPermission(user, registrarId, ConsolePermission.VIEW_REGISTRAR_DETAILS);
|
||||
ImmutableList<RegistrarPoc> am =
|
||||
tm().transact(
|
||||
() ->
|
||||
@@ -81,23 +78,14 @@ public class ContactAction extends ConsoleApiAction {
|
||||
.filter(r -> !r.getTypes().isEmpty())
|
||||
.collect(toImmutableList()));
|
||||
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
||||
consoleApiParams.response().setStatus(SC_OK);
|
||||
consoleApiParams.response().setPayload(gson.toJson(am));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postHandler(User user) {
|
||||
if (!user.getUserRoles().hasPermission(registrarId, ConsolePermission.EDIT_REGISTRAR_DETAILS)) {
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
|
||||
if (contacts.isEmpty()) {
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
consoleApiParams.response().setPayload(gson.toJson("Contacts parameter is not present"));
|
||||
return;
|
||||
}
|
||||
|
||||
checkPermission(user, registrarId, ConsolePermission.EDIT_REGISTRAR_DETAILS);
|
||||
checkArgument(contacts.isPresent(), "Contacts parameter is not present");
|
||||
Registrar registrar =
|
||||
Registrar.loadByRegistrarId(registrarId)
|
||||
.orElseThrow(
|
||||
@@ -120,12 +108,10 @@ public class ContactAction extends ConsoleApiAction {
|
||||
} catch (FormException e) {
|
||||
logger.atWarning().withCause(e).log(
|
||||
"Error processing contacts post request for registrar: %s", registrarId);
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
consoleApiParams.response().setPayload(e.getMessage());
|
||||
return;
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
|
||||
RegistrarPoc.updateContacts(registrar, updatedContacts);
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
||||
consoleApiParams.response().setStatus(SC_OK);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,10 +14,13 @@
|
||||
|
||||
package google.registry.ui.server.console.settings;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.request.Action.Method.POST;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_FORBIDDEN;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import google.registry.flows.certs.CertificateChecker;
|
||||
import google.registry.flows.certs.CertificateChecker.InsecureCertificateException;
|
||||
import google.registry.model.console.ConsolePermission;
|
||||
@@ -62,22 +65,14 @@ public class SecurityAction extends ConsoleApiAction {
|
||||
|
||||
@Override
|
||||
protected void postHandler(User user) {
|
||||
if (!user.getUserRoles().hasPermission(registrarId, ConsolePermission.EDIT_REGISTRAR_DETAILS)) {
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
|
||||
if (registrar.isEmpty()) {
|
||||
setFailedResponse(
|
||||
"'registrar' parameter is not present", HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
checkPermission(user, registrarId, ConsolePermission.EDIT_REGISTRAR_DETAILS);
|
||||
checkArgument(registrar.isPresent(), "'registrar' parameter is not present");
|
||||
|
||||
Registrar savedRegistrar;
|
||||
try {
|
||||
savedRegistrar = registrarAccessor.getRegistrar(registrarId);
|
||||
} catch (RegistrarAccessDeniedException e) {
|
||||
setFailedResponse(e.getMessage(), HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
setFailedResponse(e.getMessage(), SC_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -111,12 +106,11 @@ public class SecurityAction extends ConsoleApiAction {
|
||||
}
|
||||
}
|
||||
} catch (InsecureCertificateException e) {
|
||||
setFailedResponse(
|
||||
"Invalid certificate in parameter", HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
setFailedResponse("Invalid certificate in parameter", SC_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
|
||||
tm().put(updatedRegistrar.build());
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
||||
consoleApiParams.response().setStatus(SC_OK);
|
||||
}
|
||||
}
|
||||
|
||||
+12
-19
@@ -14,10 +14,12 @@
|
||||
|
||||
package google.registry.ui.server.console.settings;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.request.Action.Method.POST;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_FORBIDDEN;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import google.registry.model.console.ConsolePermission;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
@@ -45,8 +47,8 @@ import javax.inject.Inject;
|
||||
public class WhoisRegistrarFieldsAction extends ConsoleApiAction {
|
||||
|
||||
static final String PATH = "/console-api/settings/whois-fields";
|
||||
private AuthenticatedRegistrarAccessor registrarAccessor;
|
||||
private Optional<Registrar> registrar;
|
||||
private final AuthenticatedRegistrarAccessor registrarAccessor;
|
||||
private final Optional<Registrar> registrar;
|
||||
|
||||
@Inject
|
||||
public WhoisRegistrarFieldsAction(
|
||||
@@ -60,19 +62,9 @@ public class WhoisRegistrarFieldsAction extends ConsoleApiAction {
|
||||
|
||||
@Override
|
||||
protected void postHandler(User user) {
|
||||
if (registrar.isEmpty()) {
|
||||
setFailedResponse(
|
||||
"'registrar' parameter is not present", HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!user.getUserRoles()
|
||||
.hasPermission(
|
||||
registrar.get().getRegistrarId(), ConsolePermission.EDIT_REGISTRAR_DETAILS)) {
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
|
||||
checkArgument(registrar.isPresent(), "'registrar' parameter is not present");
|
||||
checkPermission(
|
||||
user, registrar.get().getRegistrarId(), ConsolePermission.EDIT_REGISTRAR_DETAILS);
|
||||
tm().transact(() -> loadAndModifyRegistrar(registrar.get()));
|
||||
}
|
||||
|
||||
@@ -82,8 +74,7 @@ public class WhoisRegistrarFieldsAction extends ConsoleApiAction {
|
||||
// reload to make sure the object has all the correct fields
|
||||
savedRegistrar = registrarAccessor.getRegistrar(providedRegistrar.getRegistrarId());
|
||||
} catch (RegistrarAccessDeniedException e) {
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
consoleApiParams.response().setPayload(e.getMessage());
|
||||
setFailedResponse(e.getMessage(), SC_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -91,7 +82,9 @@ public class WhoisRegistrarFieldsAction extends ConsoleApiAction {
|
||||
newRegistrar.setWhoisServer(providedRegistrar.getWhoisServer());
|
||||
newRegistrar.setUrl(providedRegistrar.getUrl());
|
||||
newRegistrar.setLocalizedAddress(providedRegistrar.getLocalizedAddress());
|
||||
newRegistrar.setPhoneNumber(providedRegistrar.getPhoneNumber());
|
||||
newRegistrar.setFaxNumber(providedRegistrar.getFaxNumber());
|
||||
tm().put(newRegistrar.build());
|
||||
consoleApiParams.response().setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
||||
consoleApiParams.response().setStatus(SC_OK);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import google.registry.request.RequestScope;
|
||||
import google.registry.request.Response;
|
||||
import google.registry.request.auth.AuthResult;
|
||||
import google.registry.security.XsrfTokenManager;
|
||||
import google.registry.ui.server.console.ConsoleEppPasswordAction.EppPasswordData;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.Optional;
|
||||
import org.joda.time.DateTime;
|
||||
@@ -232,4 +233,11 @@ public final class RegistrarConsoleModule {
|
||||
public static Optional<String> provideSearchTerm(HttpServletRequest req) {
|
||||
return extractOptionalParameter(req, "searchTerm");
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Parameter("eppPasswordChangeRequest")
|
||||
public static Optional<EppPasswordData> provideEppPasswordChangeRequest(
|
||||
Gson gson, @OptionalJsonPayload Optional<JsonElement> payload) {
|
||||
return payload.map(s -> gson.fromJson(s, EppPasswordData.class));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,9 +14,6 @@
|
||||
|
||||
package google.registry.rde;
|
||||
|
||||
import static com.google.api.client.http.HttpStatusCodes.STATUS_CODE_BAD_REQUEST;
|
||||
import static com.google.api.client.http.HttpStatusCodes.STATUS_CODE_OK;
|
||||
import static com.google.api.client.http.HttpStatusCodes.STATUS_CODE_UNAUTHORIZED;
|
||||
import static com.google.common.net.MediaType.PLAIN_TEXT_UTF_8;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.common.Cursor.CursorType.RDE_REPORT;
|
||||
@@ -26,6 +23,9 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.loadByKey;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
|
||||
import static org.joda.time.Duration.standardDays;
|
||||
import static org.joda.time.Duration.standardSeconds;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
@@ -121,7 +121,7 @@ public class RdeReportActionTest {
|
||||
gcsUtils.createFromBytes(reportFile, Ghostryde.encode(REPORT_XML.read(), encryptKey));
|
||||
tm().transact(() -> RdeRevision.saveRevision("test", DateTime.parse("2006-06-06TZ"), FULL, 0));
|
||||
when(httpUrlConnection.getOutputStream()).thenReturn(connectionOutputStream);
|
||||
when(httpUrlConnection.getResponseCode()).thenReturn(STATUS_CODE_OK);
|
||||
when(httpUrlConnection.getResponseCode()).thenReturn(SC_OK);
|
||||
when(httpUrlConnection.getInputStream()).thenReturn(IIRDEA_GOOD_XML.openBufferedStream());
|
||||
}
|
||||
|
||||
@@ -263,7 +263,7 @@ public class RdeReportActionTest {
|
||||
|
||||
@Test
|
||||
void testRunWithLock_badRequest_throws500WithErrorInfo() throws Exception {
|
||||
when(httpUrlConnection.getResponseCode()).thenReturn(STATUS_CODE_BAD_REQUEST);
|
||||
when(httpUrlConnection.getResponseCode()).thenReturn(SC_BAD_REQUEST);
|
||||
when(httpUrlConnection.getErrorStream()).thenReturn(IIRDEA_BAD_XML.openBufferedStream());
|
||||
InternalServerErrorException thrown =
|
||||
assertThrows(
|
||||
@@ -274,7 +274,7 @@ public class RdeReportActionTest {
|
||||
|
||||
@Test
|
||||
void testRunWithLock_notAuthorized() throws Exception {
|
||||
when(httpUrlConnection.getResponseCode()).thenReturn(STATUS_CODE_UNAUTHORIZED);
|
||||
when(httpUrlConnection.getResponseCode()).thenReturn(SC_UNAUTHORIZED);
|
||||
UrlConnectionException thrown =
|
||||
assertThrows(
|
||||
UrlConnectionException.class, () -> createAction().runWithLock(loadRdeReportCursor()));
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
|
||||
package google.registry.reporting.icann;
|
||||
|
||||
import static com.google.api.client.http.HttpStatusCodes.STATUS_CODE_BAD_REQUEST;
|
||||
import static com.google.api.client.http.HttpStatusCodes.STATUS_CODE_OK;
|
||||
import static com.google.api.client.http.HttpStatusCodes.STATUS_CODE_SERVER_ERROR;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -61,7 +61,7 @@ class IcannHttpReporterTest {
|
||||
createTld("test");
|
||||
createTld("xn--abc123");
|
||||
when(connection.getOutputStream()).thenReturn(outputStream);
|
||||
when(connection.getResponseCode()).thenReturn(STATUS_CODE_OK);
|
||||
when(connection.getResponseCode()).thenReturn(SC_OK);
|
||||
when(connection.getInputStream()).thenReturn(IIRDEA_GOOD_XML.openBufferedStream());
|
||||
reporter.urlConnectionService = urlConnectionService;
|
||||
reporter.password = "fakePass";
|
||||
@@ -99,7 +99,7 @@ class IcannHttpReporterTest {
|
||||
|
||||
@Test
|
||||
void testFail_BadIirdeaResponse() throws Exception {
|
||||
when(connection.getResponseCode()).thenReturn(STATUS_CODE_BAD_REQUEST);
|
||||
when(connection.getResponseCode()).thenReturn(SC_BAD_REQUEST);
|
||||
when(connection.getErrorStream()).thenReturn(IIRDEA_BAD_XML.openBufferedStream());
|
||||
assertThat(reporter.send(FAKE_PAYLOAD, "test-transactions-201706.csv")).isFalse();
|
||||
verify(connection).getErrorStream();
|
||||
@@ -107,7 +107,7 @@ class IcannHttpReporterTest {
|
||||
|
||||
@Test
|
||||
void testFail_OtherBadHttpResponse() throws Exception {
|
||||
when(connection.getResponseCode()).thenReturn(STATUS_CODE_SERVER_ERROR);
|
||||
when(connection.getResponseCode()).thenReturn(SC_INTERNAL_SERVER_ERROR);
|
||||
assertThat(reporter.send(FAKE_PAYLOAD, "test-transactions-201706.csv")).isFalse();
|
||||
verify(connection, times(0)).getInputStream();
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public final class RegistryTestServerMain {
|
||||
names = "--address",
|
||||
description = "Listening address.",
|
||||
validateWith = HostAndPortParameter.class)
|
||||
private HostAndPort address = HostAndPort.fromString("[::]:8080");
|
||||
private HostAndPort address = HostAndPort.fromString("[::1]:8080");
|
||||
|
||||
@Parameter(names = "--fixtures", description = "Fixtures to load into the DB.")
|
||||
private List<Fixture> fixtures = ImmutableList.of(Fixture.BASIC);
|
||||
|
||||
+9
-13
@@ -16,10 +16,12 @@ package google.registry.ui.server.console;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_NOT_FOUND;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.Gson;
|
||||
import google.registry.model.console.RegistrarRole;
|
||||
@@ -68,8 +70,7 @@ public class ConsoleDomainGetActionTest {
|
||||
.build()))),
|
||||
"exists.tld");
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_OK);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getPayload())
|
||||
.isEqualTo(
|
||||
"{\"domainName\":\"exists.tld\",\"adminContact\":{\"key\":\"3-ROID\",\"kind\":"
|
||||
@@ -88,8 +89,7 @@ public class ConsoleDomainGetActionTest {
|
||||
void testFailure_emptyAuth() {
|
||||
ConsoleDomainGetAction action = createAction(AuthResult.NOT_AUTHENTICATED, "exists.tld");
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_UNAUTHORIZED);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -97,8 +97,7 @@ public class ConsoleDomainGetActionTest {
|
||||
ConsoleDomainGetAction action =
|
||||
createAction(AuthResult.createApp("service@registry.example"), "exists.tld");
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_UNAUTHORIZED);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -109,8 +108,7 @@ public class ConsoleDomainGetActionTest {
|
||||
UserAuthInfo.create(mock(com.google.appengine.api.users.User.class), false)),
|
||||
"exists.tld");
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_UNAUTHORIZED);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -120,8 +118,7 @@ public class ConsoleDomainGetActionTest {
|
||||
AuthResult.createUser(UserAuthInfo.create(createUser(new UserRoles.Builder().build()))),
|
||||
"exists.tld");
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_NOT_FOUND);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -132,8 +129,7 @@ public class ConsoleDomainGetActionTest {
|
||||
UserAuthInfo.create(createUser(new UserRoles.Builder().setIsAdmin(true).build()))),
|
||||
"nonexistent.tld");
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_NOT_FOUND);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_NOT_FOUND);
|
||||
}
|
||||
|
||||
private User createUser(UserRoles userRoles) {
|
||||
|
||||
+4
-7
@@ -20,9 +20,9 @@ import static google.registry.testing.DatabaseHelper.createAdminUser;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
|
||||
import static google.registry.testing.DatabaseHelper.persistDomainAsDeleted;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.gson.Gson;
|
||||
import google.registry.model.EppResourceUtils;
|
||||
@@ -230,15 +230,13 @@ public class ConsoleDomainListActionTest {
|
||||
void testFailure_invalidResultsPerPage() {
|
||||
ConsoleDomainListAction action = createAction("TheRegistrar", null, 0, 0, null, null);
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_BAD_REQUEST);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getPayload())
|
||||
.isEqualTo("Results per page must be between 1 and 500 inclusive");
|
||||
|
||||
action = createAction("TheRegistrar", null, 0, 501, null, null);
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_BAD_REQUEST);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getPayload())
|
||||
.isEqualTo("Results per page must be between 1 and 500 inclusive");
|
||||
}
|
||||
@@ -247,8 +245,7 @@ public class ConsoleDomainListActionTest {
|
||||
void testFailure_invalidPageNumber() {
|
||||
ConsoleDomainListAction action = createAction("TheRegistrar", null, -1, 10, null, null);
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_BAD_REQUEST);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getPayload())
|
||||
.isEqualTo("Page number must be non-negative");
|
||||
}
|
||||
|
||||
+4
-4
@@ -16,9 +16,10 @@ package google.registry.ui.server.console;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_FORBIDDEN;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.gson.Gson;
|
||||
import google.registry.model.console.GlobalRole;
|
||||
@@ -82,7 +83,7 @@ class ConsoleDumDownloadActionTest {
|
||||
"1exists.tld,2024-04-15 00:00:00.001+00,2025-02-09 00:00:00.001+00,{INACTIVE}",
|
||||
"0exists.tld,2024-04-15 00:00:00+00,2025-02-09 00:00:00+00,{INACTIVE}");
|
||||
FakeResponse response = (FakeResponse) consoleApiParams.response();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
ImmutableList<String> actual =
|
||||
ImmutableList.copyOf(response.getStringWriter().toString().split("\r\n"));
|
||||
assertThat(actual).containsExactlyElementsIn(expected);
|
||||
@@ -99,8 +100,7 @@ class ConsoleDumDownloadActionTest {
|
||||
AuthResult authResult = AuthResult.createUser(UserAuthInfo.create(user));
|
||||
ConsoleDumDownloadAction action = createAction(Optional.of(authResult));
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_FORBIDDEN);
|
||||
}
|
||||
|
||||
private ConsoleDumDownloadAction createAction(Optional<AuthResult> maybeAuthResult) {
|
||||
|
||||
+47
-74
@@ -19,14 +19,16 @@ import static google.registry.request.auth.AuthenticatedRegistrarAccessor.Role.O
|
||||
import static google.registry.testing.DatabaseHelper.loadRegistrar;
|
||||
import static google.registry.testing.DatabaseHelper.persistNewRegistrar;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_FORBIDDEN;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSetMultimap;
|
||||
import com.google.gson.Gson;
|
||||
import google.registry.flows.PasswordOnlyTransportCredentials;
|
||||
@@ -37,14 +39,20 @@ import google.registry.model.console.UserRoles;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions;
|
||||
import google.registry.request.Action;
|
||||
import google.registry.request.RequestModule;
|
||||
import google.registry.request.auth.AuthResult;
|
||||
import google.registry.request.auth.AuthenticatedRegistrarAccessor;
|
||||
import google.registry.request.auth.UserAuthInfo;
|
||||
import google.registry.testing.FakeConsoleApiParams;
|
||||
import google.registry.testing.FakeResponse;
|
||||
import google.registry.tools.GsonUtils;
|
||||
import google.registry.ui.server.console.ConsoleEppPasswordAction.EppPasswordData;
|
||||
import google.registry.ui.server.registrar.ConsoleApiParams;
|
||||
import google.registry.ui.server.registrar.RegistrarConsoleModule;
|
||||
import google.registry.util.EmailMessage;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.Optional;
|
||||
import javax.mail.internet.AddressException;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
@@ -54,6 +62,9 @@ import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
class ConsoleEppPasswordActionTest {
|
||||
private static final Gson GSON = GsonUtils.provideGson();
|
||||
private static String eppPostData =
|
||||
"{\"registrarId\":\"%s\",\"oldPassword\":\"%s\",\"newPassword\":\"%s\",\"newPasswordRepeat\":\"%s\"}";
|
||||
|
||||
private ConsoleApiParams consoleApiParams;
|
||||
protected PasswordOnlyTransportCredentials credentials = new PasswordOnlyTransportCredentials();
|
||||
private FakeResponse response;
|
||||
@@ -78,68 +89,38 @@ class ConsoleEppPasswordActionTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_emptyParams() {
|
||||
ConsoleEppPasswordAction action = createAction();
|
||||
void testFailure_emptyParams() throws IOException {
|
||||
ConsoleEppPasswordAction action = createAction("", "", "", "");
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_BAD_REQUEST);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getPayload())
|
||||
.isEqualTo("Missing parameter: registrarId");
|
||||
.isEqualTo("Missing param(s): registrarId");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_passwordsDontMatch() {
|
||||
ConsoleEppPasswordAction action = createAction();
|
||||
setParams(
|
||||
ImmutableMap.of(
|
||||
"registrarId",
|
||||
"registrarId",
|
||||
"oldPassword",
|
||||
"oldPassword",
|
||||
"newPassword",
|
||||
"newPassword",
|
||||
"newPasswordRepeat",
|
||||
"newPasswordRepeat"));
|
||||
void testFailure_passwordsDontMatch() throws IOException {
|
||||
ConsoleEppPasswordAction action =
|
||||
createAction("registrarId", "oldPassword", "newPassword", "newPasswordRepeat");
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_BAD_REQUEST);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getPayload())
|
||||
.contains("New password fields don't match");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_existingPasswordIncorrect() {
|
||||
ConsoleEppPasswordAction action = createAction();
|
||||
setParams(
|
||||
ImmutableMap.of(
|
||||
"registrarId",
|
||||
"registrarId",
|
||||
"oldPassword",
|
||||
"oldPassword",
|
||||
"newPassword",
|
||||
"randomPasword",
|
||||
"newPasswordRepeat",
|
||||
"randomPasword"));
|
||||
void testFailure_existingPasswordIncorrect() throws IOException {
|
||||
ConsoleEppPasswordAction action =
|
||||
createAction("registrarId", "oldPassword", "randomPasword", "randomPasword");
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_FORBIDDEN);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getPayload())
|
||||
.contains("Registrar password is incorrect");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_sendsConfirmationEmail() throws AddressException {
|
||||
ConsoleEppPasswordAction action = createAction();
|
||||
setParams(
|
||||
ImmutableMap.of(
|
||||
"registrarId",
|
||||
"registrarId",
|
||||
"oldPassword",
|
||||
"foobar",
|
||||
"newPassword",
|
||||
"randomPassword",
|
||||
"newPasswordRepeat",
|
||||
"randomPassword"));
|
||||
void testSuccess_sendsConfirmationEmail() throws IOException, AddressException {
|
||||
ConsoleEppPasswordAction action =
|
||||
createAction("registrarId", "foobar", "randomPassword", "randomPassword");
|
||||
action.run();
|
||||
verify(gmailClient, times(1))
|
||||
.sendEmail(
|
||||
@@ -148,42 +129,24 @@ class ConsoleEppPasswordActionTest {
|
||||
"Dear registrarId name,\n"
|
||||
+ "This is to confirm that your account password has been changed.",
|
||||
new InternetAddress("testEmail@google.com")));
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_passwordUpdated() {
|
||||
ConsoleEppPasswordAction action = createAction();
|
||||
setParams(
|
||||
ImmutableMap.of(
|
||||
"registrarId",
|
||||
"registrarId",
|
||||
"oldPassword",
|
||||
"foobar",
|
||||
"newPassword",
|
||||
"randomPassword",
|
||||
"newPasswordRepeat",
|
||||
"randomPassword"));
|
||||
void testSuccess_passwordUpdated() throws IOException {
|
||||
ConsoleEppPasswordAction action =
|
||||
createAction("registrarId", "foobar", "randomPassword", "randomPassword");
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_OK);
|
||||
assertDoesNotThrow(
|
||||
() -> {
|
||||
credentials.validate(loadRegistrar("registrarId"), "randomPassword");
|
||||
});
|
||||
}
|
||||
|
||||
private void setParams(ImmutableMap<String, String> params) {
|
||||
params.entrySet().stream()
|
||||
.forEach(
|
||||
entry -> {
|
||||
when(consoleApiParams.request().getParameter(entry.getKey()))
|
||||
.thenReturn(entry.getValue());
|
||||
});
|
||||
}
|
||||
|
||||
private ConsoleEppPasswordAction createAction() {
|
||||
private ConsoleEppPasswordAction createAction(
|
||||
String registrarId, String oldPassword, String newPassword, String newPasswordRepeat)
|
||||
throws IOException {
|
||||
response = new FakeResponse();
|
||||
User user =
|
||||
new User.Builder()
|
||||
@@ -197,8 +160,18 @@ class ConsoleEppPasswordActionTest {
|
||||
AuthenticatedRegistrarAccessor.createForTesting(
|
||||
ImmutableSetMultimap.of("registrarId", OWNER));
|
||||
when(consoleApiParams.request().getMethod()).thenReturn(Action.Method.POST.toString());
|
||||
doReturn(
|
||||
new BufferedReader(
|
||||
new StringReader(
|
||||
String.format(
|
||||
eppPostData, registrarId, oldPassword, newPassword, newPasswordRepeat))))
|
||||
.when(consoleApiParams.request())
|
||||
.getReader();
|
||||
Optional<EppPasswordData> maybePasswordChangeRequest =
|
||||
RegistrarConsoleModule.provideEppPasswordChangeRequest(
|
||||
GSON, RequestModule.provideJsonBody(consoleApiParams.request(), GSON));
|
||||
|
||||
return new ConsoleEppPasswordAction(
|
||||
consoleApiParams, authenticatedRegistrarAccessor, gmailClient);
|
||||
consoleApiParams, authenticatedRegistrarAccessor, gmailClient, maybePasswordChangeRequest);
|
||||
}
|
||||
}
|
||||
|
||||
+25
-22
@@ -24,11 +24,14 @@ import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.testing.SqlHelper.getMostRecentRegistryLockByRepoId;
|
||||
import static google.registry.testing.SqlHelper.saveRegistryLock;
|
||||
import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_FORBIDDEN;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.Gson;
|
||||
import google.registry.groups.GmailClient;
|
||||
@@ -130,7 +133,7 @@ public class ConsoleRegistryLockActionTest {
|
||||
.setLockCompletionTime(fakeClock.nowUtc())
|
||||
.build());
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
assertThat(response.getPayload())
|
||||
.isEqualTo(
|
||||
"""
|
||||
@@ -222,7 +225,7 @@ public class ConsoleRegistryLockActionTest {
|
||||
saveRegistryLock(unlockedLock);
|
||||
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
// We should include all the locks that are currently locked, which does not include pending
|
||||
// locks or completed unlocks
|
||||
assertThat(response.getPayload())
|
||||
@@ -252,7 +255,7 @@ public class ConsoleRegistryLockActionTest {
|
||||
@Test
|
||||
void testGet_noLocks() {
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
assertThat(response.getPayload()).isEqualTo("[]");
|
||||
}
|
||||
|
||||
@@ -265,7 +268,7 @@ public class ConsoleRegistryLockActionTest {
|
||||
.build();
|
||||
action = createGetAction();
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -282,14 +285,14 @@ public class ConsoleRegistryLockActionTest {
|
||||
.build();
|
||||
action = createGetAction();
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPost_lock() throws Exception {
|
||||
action = createDefaultPostAction(true);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
assertThat(getMostRecentRegistryLockByRepoId(defaultDomain.getRepoId())).isPresent();
|
||||
verifyEmail();
|
||||
// Doesn't actually change the status values (hasn't been verified)
|
||||
@@ -302,7 +305,7 @@ public class ConsoleRegistryLockActionTest {
|
||||
persistResource(defaultDomain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
action = createDefaultPostAction(false);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
verifyEmail();
|
||||
// Doesn't actually change the status values (hasn't been verified)
|
||||
assertThat(loadByEntity(defaultDomain).getStatusValues())
|
||||
@@ -320,7 +323,7 @@ public class ConsoleRegistryLockActionTest {
|
||||
"registryLockPassword",
|
||||
Optional.of(Duration.standardDays(1).getMillis()));
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
verifyEmail();
|
||||
RegistryLock savedUnlockRequest =
|
||||
getMostRecentRegistryLockByRepoId(defaultDomain.getRepoId()).get();
|
||||
@@ -343,7 +346,7 @@ public class ConsoleRegistryLockActionTest {
|
||||
.build();
|
||||
action = createDefaultPostAction(false);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
verifyEmail();
|
||||
}
|
||||
|
||||
@@ -356,7 +359,7 @@ public class ConsoleRegistryLockActionTest {
|
||||
.build();
|
||||
action = createPostAction("example.test", true, "", Optional.empty());
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
verifyEmail();
|
||||
}
|
||||
|
||||
@@ -369,7 +372,7 @@ public class ConsoleRegistryLockActionTest {
|
||||
.build();
|
||||
action = createDefaultPostAction(true);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -386,14 +389,14 @@ public class ConsoleRegistryLockActionTest {
|
||||
.build();
|
||||
action = createDefaultPostAction(true);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPost_failure_unlock_noLock() throws Exception {
|
||||
action = createDefaultPostAction(false);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_BAD_REQUEST);
|
||||
assertThat(response.getPayload()).isEqualTo("Domain example.test is already unlocked");
|
||||
}
|
||||
|
||||
@@ -407,7 +410,7 @@ public class ConsoleRegistryLockActionTest {
|
||||
persistResource(defaultDomain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
action = createDefaultPostAction(false);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_BAD_REQUEST);
|
||||
assertThat(response.getPayload())
|
||||
.isEqualTo("Non-admin user cannot unlock admin-locked domain example.test");
|
||||
}
|
||||
@@ -423,7 +426,7 @@ public class ConsoleRegistryLockActionTest {
|
||||
action =
|
||||
createPostAction("otherregistrar.test", true, "registryLockPassword", Optional.empty());
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_BAD_REQUEST);
|
||||
assertThat(response.getPayload())
|
||||
.isEqualTo("Domain otherregistrar.test is not owned by registrar TheRegistrar");
|
||||
}
|
||||
@@ -434,7 +437,7 @@ public class ConsoleRegistryLockActionTest {
|
||||
loadRegistrar("TheRegistrar").asBuilder().setRegistryLockAllowed(false).build());
|
||||
action = createDefaultPostAction(true);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_BAD_REQUEST);
|
||||
assertThat(response.getPayload())
|
||||
.isEqualTo("Registry lock not allowed for registrar TheRegistrar");
|
||||
}
|
||||
@@ -444,7 +447,7 @@ public class ConsoleRegistryLockActionTest {
|
||||
user = user.asBuilder().setRegistryLockEmailAddress(null).build();
|
||||
action = createDefaultPostAction(true);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_BAD_REQUEST);
|
||||
assertThat(response.getPayload()).isEqualTo("User has no registry lock email address");
|
||||
}
|
||||
|
||||
@@ -452,7 +455,7 @@ public class ConsoleRegistryLockActionTest {
|
||||
void testPost_failure_badPassword() throws Exception {
|
||||
action = createPostAction("example.test", true, "badPassword", Optional.empty());
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_UNAUTHORIZED);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -460,7 +463,7 @@ public class ConsoleRegistryLockActionTest {
|
||||
saveRegistryLock(createDefaultLockBuilder().build());
|
||||
action = createDefaultPostAction(true);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_BAD_REQUEST);
|
||||
assertThat(response.getPayload())
|
||||
.isEqualTo("A pending or completed lock action already exists for example.test");
|
||||
}
|
||||
@@ -470,7 +473,7 @@ public class ConsoleRegistryLockActionTest {
|
||||
persistResource(defaultDomain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
action = createDefaultPostAction(true);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_BAD_REQUEST);
|
||||
assertThat(response.getPayload()).isEqualTo("Domain example.test is already locked");
|
||||
}
|
||||
|
||||
@@ -484,7 +487,7 @@ public class ConsoleRegistryLockActionTest {
|
||||
.build());
|
||||
action = createDefaultPostAction(false);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_BAD_REQUEST);
|
||||
assertThat(response.getPayload()).isEqualTo("Domain example.test is already unlocked");
|
||||
}
|
||||
|
||||
|
||||
@@ -16,9 +16,10 @@ package google.registry.ui.server.console;
|
||||
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.gson.Gson;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions;
|
||||
@@ -67,8 +68,7 @@ class ConsoleUserDataActionTest {
|
||||
ConsoleUserDataAction action =
|
||||
createAction(Optional.of(FakeConsoleApiParams.get(Optional.of(authResult))));
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_OK);
|
||||
Map jsonObject =
|
||||
GSON.fromJson(((FakeResponse) consoleApiParams.response()).getPayload(), Map.class);
|
||||
assertThat(jsonObject)
|
||||
@@ -91,8 +91,7 @@ class ConsoleUserDataActionTest {
|
||||
void testFailure_notAConsoleUser() throws IOException {
|
||||
ConsoleUserDataAction action = createAction(Optional.empty());
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_UNAUTHORIZED);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
private ConsoleUserDataAction createAction(Optional<ConsoleApiParams> maybeConsoleApiParams)
|
||||
|
||||
@@ -20,10 +20,12 @@ import static google.registry.testing.DatabaseHelper.loadRegistrar;
|
||||
import static google.registry.testing.DatabaseHelper.persistNewRegistrar;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.testing.SqlHelper.saveRegistrar;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_FORBIDDEN;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.Gson;
|
||||
@@ -99,10 +101,15 @@ class RegistrarsActionTest {
|
||||
new JpaTestExtensions.Builder().buildIntegrationTestExtension();
|
||||
|
||||
@Test
|
||||
void testSuccess_onlyRealRegistrars() {
|
||||
void testSuccess_onlyRealAndOteRegistrars() {
|
||||
Registrar registrar = persistNewRegistrar("registrarId");
|
||||
registrar = registrar.asBuilder().setType(Registrar.Type.TEST).setIanaIdentifier(null).build();
|
||||
persistResource(registrar);
|
||||
|
||||
registrar = persistNewRegistrar("registrarId2");
|
||||
registrar = registrar.asBuilder().setType(Registrar.Type.OTE).setIanaIdentifier(null).build();
|
||||
persistResource(registrar);
|
||||
|
||||
RegistrarsAction action =
|
||||
createAction(
|
||||
Action.Method.GET,
|
||||
@@ -111,14 +118,15 @@ class RegistrarsActionTest {
|
||||
createUser(
|
||||
new UserRoles.Builder().setGlobalRole(GlobalRole.SUPPORT_LEAD).build()))));
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_OK);
|
||||
String payload = ((FakeResponse) consoleApiParams.response()).getPayload();
|
||||
assertThat(
|
||||
ImmutableList.of("\"registrarId\":\"NewRegistrar\"", "\"registrarId\":\"TheRegistrar\"")
|
||||
.stream()
|
||||
.allMatch(s -> payload.contains(s)))
|
||||
.isTrue();
|
||||
|
||||
var actualRegistrarIds =
|
||||
ImmutableList.copyOf(GSON.fromJson(payload, Registrar[].class)).stream()
|
||||
.map(r -> r.getRegistrarId())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(actualRegistrarIds).containsExactly("NewRegistrar", "TheRegistrar", "registrarId2");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -131,8 +139,7 @@ class RegistrarsActionTest {
|
||||
UserAuthInfo.create(
|
||||
createUser(new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).build()))));
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_OK);
|
||||
String payload = ((FakeResponse) consoleApiParams.response()).getPayload();
|
||||
assertThat(
|
||||
ImmutableList.of(
|
||||
@@ -152,8 +159,7 @@ class RegistrarsActionTest {
|
||||
AuthResult.createUser(
|
||||
UserAuthInfo.create(createUser(new UserRoles.Builder().setIsAdmin(true).build()))));
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_OK);
|
||||
Registrar r = loadRegistrar("regIdTest");
|
||||
assertThat(r).isNotNull();
|
||||
assertThat(
|
||||
@@ -183,7 +189,7 @@ class RegistrarsActionTest {
|
||||
createUser(new UserRoles.Builder().setIsAdmin(true).build()))));
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
.isEqualTo(SC_BAD_REQUEST);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getPayload())
|
||||
.isEqualTo(
|
||||
String.format(
|
||||
@@ -200,8 +206,7 @@ class RegistrarsActionTest {
|
||||
AuthResult.createUser(
|
||||
UserAuthInfo.create(createUser(new UserRoles.Builder().setIsAdmin(true).build()))));
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_BAD_REQUEST);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getPayload())
|
||||
.isEqualTo("Registrar with registrarId regIdTest already exists");
|
||||
}
|
||||
@@ -222,8 +227,7 @@ class RegistrarsActionTest {
|
||||
RegistrarRole.ACCOUNT_MANAGER_WITH_REGISTRY_LOCK))
|
||||
.build()))));
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_FORBIDDEN);
|
||||
}
|
||||
|
||||
private User createUser(UserRoles userRoles) {
|
||||
|
||||
+8
-13
@@ -21,10 +21,11 @@ import static google.registry.testing.DatabaseHelper.createAdminUser;
|
||||
import static google.registry.testing.DatabaseHelper.insertInDb;
|
||||
import static google.registry.testing.DatabaseHelper.loadAllOf;
|
||||
import static google.registry.testing.SqlHelper.saveRegistrar;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_FORBIDDEN;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.gson.Gson;
|
||||
@@ -105,8 +106,7 @@ class ContactActionTest {
|
||||
testRegistrar.getRegistrarId(),
|
||||
null);
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_OK);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getPayload())
|
||||
.isEqualTo("[" + jsonRegistrar1 + "]");
|
||||
}
|
||||
@@ -122,8 +122,7 @@ class ContactActionTest {
|
||||
testRegistrar.getRegistrarId(),
|
||||
null);
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_OK);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getPayload()).isEqualTo("[]");
|
||||
}
|
||||
|
||||
@@ -136,8 +135,7 @@ class ContactActionTest {
|
||||
testRegistrar.getRegistrarId(),
|
||||
"[" + jsonRegistrar1 + "," + jsonRegistrar2 + "]");
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_OK);
|
||||
assertThat(
|
||||
loadAllOf(RegistrarPoc.class).stream()
|
||||
.filter(r -> r.registrarId.equals(testRegistrar.getRegistrarId()))
|
||||
@@ -157,8 +155,7 @@ class ContactActionTest {
|
||||
testRegistrar.getRegistrarId(),
|
||||
"[" + jsonRegistrar1 + "," + jsonRegistrar2 + "]");
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_OK);
|
||||
HashMap<String, String> testResult = new HashMap<>();
|
||||
loadAllOf(RegistrarPoc.class).stream()
|
||||
.filter(r -> r.registrarId.equals(testRegistrar.getRegistrarId()))
|
||||
@@ -181,8 +178,7 @@ class ContactActionTest {
|
||||
testRegistrar.getRegistrarId(),
|
||||
"[" + jsonRegistrar2 + "]");
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_OK);
|
||||
assertThat(
|
||||
loadAllOf(RegistrarPoc.class).stream()
|
||||
.filter(r -> r.registrarId.equals(testRegistrar.getRegistrarId()))
|
||||
@@ -212,8 +208,7 @@ class ContactActionTest {
|
||||
testRegistrar.getRegistrarId(),
|
||||
"[" + jsonRegistrar2 + "]");
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_FORBIDDEN);
|
||||
}
|
||||
|
||||
private ContactAction createAction(
|
||||
|
||||
+2
-3
@@ -19,10 +19,10 @@ import static google.registry.testing.CertificateSamples.SAMPLE_CERT2;
|
||||
import static google.registry.testing.DatabaseHelper.loadRegistrar;
|
||||
import static google.registry.testing.SqlHelper.saveRegistrar;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSetMultimap;
|
||||
import com.google.common.collect.ImmutableSortedMap;
|
||||
@@ -94,8 +94,7 @@ class SecurityActionTest {
|
||||
UserAuthInfo.create(DatabaseHelper.createAdminUser("email@email.com"))),
|
||||
testRegistrar.getRegistrarId());
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_OK);
|
||||
Registrar r = loadRegistrar(testRegistrar.getRegistrarId());
|
||||
assertThat(r.getClientCertificateHash().get())
|
||||
.isEqualTo("GNd6ZP8/n91t9UTnpxR8aH7aAW4+CpvufYx9ViGbcMY");
|
||||
|
||||
+12
-6
@@ -16,10 +16,11 @@ package google.registry.ui.server.console.settings;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_FORBIDDEN;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSetMultimap;
|
||||
@@ -105,6 +106,10 @@ public class WhoisRegistrarFieldsActionTest {
|
||||
ImmutableMap.of(
|
||||
"whoisServer",
|
||||
"whois.nic.google",
|
||||
"phoneNumber",
|
||||
"+1.4155552671",
|
||||
"faxNumber",
|
||||
"+1.4155552672",
|
||||
"url",
|
||||
"\"https://newurl.example\"",
|
||||
"localizedAddress",
|
||||
@@ -112,16 +117,18 @@ public class WhoisRegistrarFieldsActionTest {
|
||||
+ " \"NL\", \"zip\": \"10011\", \"countryCode\": \"CA\"}"));
|
||||
WhoisRegistrarFieldsAction action = createAction();
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_OK);
|
||||
Registrar newRegistrar = Registrar.loadByRegistrarId("TheRegistrar").get(); // skip cache
|
||||
assertThat(newRegistrar.getWhoisServer()).isEqualTo("whois.nic.google");
|
||||
assertThat(newRegistrar.getUrl()).isEqualTo("https://newurl.example");
|
||||
assertThat(newRegistrar.getLocalizedAddress().toJsonMap()).isEqualTo(addressMap);
|
||||
assertThat(newRegistrar.getPhoneNumber()).isEqualTo("+1.4155552671");
|
||||
assertThat(newRegistrar.getFaxNumber()).isEqualTo("+1.4155552672");
|
||||
// the non-changed fields should be the same
|
||||
assertAboutImmutableObjects()
|
||||
.that(newRegistrar)
|
||||
.isEqualExceptFields(oldRegistrar, "whoisServer", "url", "localizedAddress");
|
||||
.isEqualExceptFields(
|
||||
oldRegistrar, "whoisServer", "url", "localizedAddress", "phoneNumber", "faxNumber");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -141,8 +148,7 @@ public class WhoisRegistrarFieldsActionTest {
|
||||
uiRegistrarMap.put("registrarId", "NewRegistrar");
|
||||
WhoisRegistrarFieldsAction action = createAction(onlyTheRegistrar);
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus())
|
||||
.isEqualTo(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_FORBIDDEN);
|
||||
// should be no change
|
||||
assertThat(DatabaseHelper.loadByEntity(newRegistrar)).isEqualTo(newRegistrar);
|
||||
}
|
||||
|
||||
+3
-3
@@ -24,9 +24,9 @@ import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.testing.SqlHelper.saveRegistryLock;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_FORBIDDEN;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.appengine.api.users.User;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
@@ -110,7 +110,7 @@ final class RegistryLockGetActionTest {
|
||||
|
||||
action.authResult = AuthResult.createUser(UserAuthInfo.create(consoleUser));
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
assertThat(GSON.fromJson(response.getPayload(), Map.class))
|
||||
.containsExactly(
|
||||
"status",
|
||||
@@ -220,7 +220,7 @@ final class RegistryLockGetActionTest {
|
||||
saveRegistryLock(unlockedLock);
|
||||
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
assertThat(GSON.fromJson(response.getPayload(), Map.class))
|
||||
.containsExactly(
|
||||
"status", "SUCCESS",
|
||||
|
||||
@@ -261,11 +261,11 @@ td.section {
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="property_name">generated on</td>
|
||||
<td class="property_value">2024-05-09 17:59:02.29076074</td>
|
||||
<td class="property_value">2024-05-10 19:17:39.481284329</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="property_name">last flyway file</td>
|
||||
<td id="lastFlywayFile" class="property_value">V170__user_update_registry_lock_email.sql</td>
|
||||
<td id="lastFlywayFile" class="property_value">V171__drop_create_billing_cost_columns_from_tld.sql</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -277,11 +277,11 @@ td.section {
|
||||
SchemaCrawler_Diagram
|
||||
</title>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-3493.5 4025,-3493.5 4025,4 -4,4" />
|
||||
<text text-anchor="start" x="3737" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">generated by</text>
|
||||
<text text-anchor="start" x="3820" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">SchemaCrawler 16.10.1</text>
|
||||
<text text-anchor="start" x="3736" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">generated on</text>
|
||||
<text text-anchor="start" x="3820" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">2024-05-09 17:59:02.29076074</text>
|
||||
<polygon fill="none" stroke="#888888" points="3733,-4 3733,-44 4013,-44 4013,-4 3733,-4" /> <!-- allocationtoken_a08ccbef -->
|
||||
<text text-anchor="start" x="3730.5" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">generated by</text>
|
||||
<text text-anchor="start" x="3813.5" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">SchemaCrawler 16.10.1</text>
|
||||
<text text-anchor="start" x="3729.5" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">generated on</text>
|
||||
<text text-anchor="start" x="3813.5" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">2024-05-10 19:17:39.481284329</text>
|
||||
<polygon fill="none" stroke="#888888" points="3726,-4 3726,-44 4013,-44 4013,-4 3726,-4" /> <!-- allocationtoken_a08ccbef -->
|
||||
<g id="node1" class="node">
|
||||
<title>
|
||||
allocationtoken_a08ccbef
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -168,3 +168,4 @@ V167__creat_billing_cost_transitions_not_null.sql
|
||||
V168__registry_lock_email.sql
|
||||
V169__add_more_indexes_needed_for_delete_prober_data.sql
|
||||
V170__user_update_registry_lock_email.sql
|
||||
V171__drop_create_billing_cost_columns_from_tld.sql
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
-- Copyright 2024 The Nomulus Authors. All Rights Reserved.
|
||||
--
|
||||
-- Licensed under the Apache License, Version 2.0 (the "License");
|
||||
-- you may not use this file except in compliance with the License.
|
||||
-- You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing, software
|
||||
-- distributed under the License is distributed on an "AS IS" BASIS,
|
||||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
-- See the License for the specific language governing permissions and
|
||||
-- limitations under the License.
|
||||
|
||||
alter table "Tld" drop column create_billing_cost_amount;
|
||||
alter table "Tld" drop column create_billing_cost_currency;
|
||||
@@ -1249,8 +1249,6 @@ CREATE TABLE public."Tld" (
|
||||
auto_renew_grace_period_length interval NOT NULL,
|
||||
automatic_transfer_length interval NOT NULL,
|
||||
claims_period_end timestamp with time zone NOT NULL,
|
||||
create_billing_cost_amount numeric(19,2),
|
||||
create_billing_cost_currency text,
|
||||
creation_time timestamp with time zone NOT NULL,
|
||||
currency text NOT NULL,
|
||||
dns_paused boolean NOT NULL,
|
||||
|
||||
@@ -13,6 +13,7 @@ spec:
|
||||
labels:
|
||||
app: nomulus
|
||||
spec:
|
||||
serviceAccountName: nomulus
|
||||
containers:
|
||||
- name: nomulus
|
||||
image: gcr.io/GCP_PROJECT/nomulus
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
// Copyright 2024 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
apply plugin: 'java'
|
||||
|
||||
createUberJar('buildLoadTestClient', 'loadTest', 'google.registry.client.EppClient')
|
||||
|
||||
dependencies {
|
||||
def deps = rootProject.dependencyMap
|
||||
implementation deps['joda-time:joda-time']
|
||||
implementation deps['io.netty:netty-buffer']
|
||||
implementation deps['io.netty:netty-codec']
|
||||
implementation deps['io.netty:netty-codec-http']
|
||||
implementation deps['io.netty:netty-common']
|
||||
implementation deps['io.netty:netty-handler']
|
||||
implementation deps['io.netty:netty-transport']
|
||||
implementation deps['com.google.guava:guava']
|
||||
implementation deps['org.bouncycastle:bcpg-jdk18on']
|
||||
implementation deps['org.bouncycastle:bcpkix-jdk18on']
|
||||
implementation deps['org.bouncycastle:bcprov-jdk18on']
|
||||
implementation deps['org.jcommander:jcommander']
|
||||
implementation deps['com.google.flogger:flogger']
|
||||
runtimeOnly deps['com.google.flogger:flogger-system-backend']
|
||||
}
|
||||
|
||||
task makeStagingDirectory {
|
||||
mkdir layout.buildDirectory.dir('stage')
|
||||
}
|
||||
|
||||
task copyFilesToStaging(dependsOn: makeStagingDirectory, type: Copy) {
|
||||
from layout.buildDirectory.file('libs/loadTest.jar'), "${projectDir}/certificate.pem", "${projectDir}/key.pem"
|
||||
into layout.buildDirectory.dir('stage')
|
||||
}
|
||||
|
||||
task deployLoadTestsToInstances (dependsOn: copyFilesToStaging, type: Exec) {
|
||||
executable "sh"
|
||||
workingDir "${projectDir}/"
|
||||
args "-c", "./deploy.sh"
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
# Copyright 2024 The Nomulus Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
HOSTS=$(gcloud compute instances list | awk '/^loadtest/ { print $5 }')
|
||||
for host in $HOSTS; do rsync -avz ./build/stage/ $host:test-client/; done
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
# Copyright 2024 The Nomulus Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Find and delete the instances used for load testing
|
||||
|
||||
gcloud compute instances list --filter="name ~ loadtest.*" --zones us-east4-a \
|
||||
--format="value(name)" | xargs gcloud compute instances delete --zone us-east4-a
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
#!/bin/bash
|
||||
# Copyright 2024 The Nomulus Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Create the instances - modify this number for the amount of instances you
|
||||
# would like to use for your load test
|
||||
gcloud compute instances create loadtest-{1..2} --machine-type g1-small \
|
||||
--image-family ubuntu-2204-lts --image-project ubuntu-os-cloud --zone us-east4-a
|
||||
|
||||
sleep 10
|
||||
|
||||
# Get all the created load tests instances
|
||||
HOSTS=$(gcloud compute instances list | awk '/^loadtest/ { print $5 }')
|
||||
|
||||
#Install rsync and Java - Retry is needed here since ssh connection will fail until instances are fully provisioned
|
||||
for host in $HOSTS;
|
||||
do
|
||||
for i in {1..60}; do
|
||||
if ssh $host 'sudo apt-get -y update &&
|
||||
sudo apt-get -y upgrade &&
|
||||
sudo apt-get -y install rsync &&
|
||||
sudo apt-get -y install openjdk-21-jdk'; then
|
||||
break
|
||||
else
|
||||
sleep 5
|
||||
fi
|
||||
done
|
||||
done
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
# Copyright 2024 The Nomulus Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
HOSTS=$(gcloud compute instances list | awk '/^loadtest/ { print $5 }')
|
||||
|
||||
for host in $HOSTS;
|
||||
do ssh $host 'cd test-client/ &&
|
||||
java -jar loadTest.jar --host epp.example --certificate certificate.pem -k key.pem -pw examplePassword -ft';
|
||||
done
|
||||
@@ -0,0 +1,353 @@
|
||||
// Copyright 2024 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package google.registry.client;
|
||||
|
||||
import static com.google.common.io.Resources.getResource;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.joda.time.DateTimeZone.UTC;
|
||||
|
||||
import com.beust.jcommander.IStringConverter;
|
||||
import com.beust.jcommander.JCommander;
|
||||
import com.beust.jcommander.Parameter;
|
||||
import com.beust.jcommander.Parameters;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.common.io.Resources;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
|
||||
import io.netty.handler.codec.LengthFieldPrepender;
|
||||
import io.netty.handler.logging.LogLevel;
|
||||
import io.netty.handler.logging.LoggingHandler;
|
||||
import io.netty.handler.ssl.SslContextBuilder;
|
||||
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import io.netty.util.AttributeKey;
|
||||
import io.netty.util.concurrent.Promise;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.KeyPair;
|
||||
import java.security.Security;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.time.Duration;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import org.bouncycastle.cert.X509CertificateHolder;
|
||||
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.openssl.PEMKeyPair;
|
||||
import org.bouncycastle.openssl.PEMParser;
|
||||
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/** A simple EPP client that can be used for load testing. */
|
||||
@Parameters(separators = " =")
|
||||
@SuppressWarnings("FutureReturnValueIgnored")
|
||||
public class EppClient implements Runnable {
|
||||
|
||||
static {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
}
|
||||
|
||||
private static final String LOGIN_FILE = "login.xml";
|
||||
private static final String LOGOUT_FILE = "logout.xml";
|
||||
static final AttributeKey<ArrayList<ZonedDateTime>> REQUEST_SENT =
|
||||
AttributeKey.valueOf("REQUEST_SENT");
|
||||
static final AttributeKey<ArrayList<ZonedDateTime>> RESPONSE_RECEIVED =
|
||||
AttributeKey.valueOf("RESPONSE_RECEIVED");
|
||||
static final AttributeKey<Integer> CHANNEL_NUMBER = AttributeKey.valueOf("CHANNEL_NUMBER");
|
||||
static final AttributeKey<Path> LOGGING_LOCATION = AttributeKey.valueOf("LOGGING_LOCATION");
|
||||
static final AttributeKey<Boolean> FORCE_TERMINATE = AttributeKey.valueOf("FORCE_TERMINATE");
|
||||
static final AttributeKey<ExecutorService> LOGGING_EXECUTOR =
|
||||
AttributeKey.valueOf("LOGGING_EXECUTOR");
|
||||
static final AttributeKey<Iterator<byte[]>> INPUT_ITERATOR =
|
||||
AttributeKey.valueOf("INPUT_ITERATOR");
|
||||
static final AttributeKey<Promise<Void>> LOGGING_REQUEST_COMPLETE =
|
||||
AttributeKey.valueOf("LOGGING_REQUEST_COMPLETE");
|
||||
private static final int PORT = 700;
|
||||
private static final int TIMEOUT_SECONDS = 600;
|
||||
|
||||
public static class InetAddressConverter implements IStringConverter<InetAddress> {
|
||||
|
||||
@Override
|
||||
public InetAddress convert(String host) {
|
||||
try {
|
||||
return InetAddress.getByName(host);
|
||||
} catch (UnknownHostException e) {
|
||||
throw new IllegalArgumentException(host, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Parameter(
|
||||
names = {"--help"},
|
||||
description = "Print this help message.",
|
||||
help = true)
|
||||
private boolean help = false;
|
||||
|
||||
@Parameter(
|
||||
names = {"--host", "-h"},
|
||||
description = "Epp server hostname/IP to connect to.",
|
||||
converter = InetAddressConverter.class,
|
||||
required = true)
|
||||
private InetAddress host = null;
|
||||
|
||||
@Parameter(
|
||||
names = {"--certificate"},
|
||||
description = "Certificate pem file.",
|
||||
required = true)
|
||||
private String certFileName = null;
|
||||
|
||||
@Parameter(
|
||||
names = {"--key", "-k"},
|
||||
description = "Private key pem file.",
|
||||
required = true)
|
||||
private String keyFileName = null;
|
||||
|
||||
@Parameter(
|
||||
names = {"--connections", "-cn"},
|
||||
description = "Number of connections that are made to the EPP server.")
|
||||
private int connections = 1;
|
||||
|
||||
@Parameter(
|
||||
names = {"--client", "-c"},
|
||||
description = "Registrar client id.")
|
||||
private String client = "proxy";
|
||||
|
||||
@Parameter(
|
||||
names = {"--password", "-pw"},
|
||||
description = "Registrar password.")
|
||||
private String password = "abcde12345";
|
||||
|
||||
@Parameter(
|
||||
names = {"--force_terminate", "-ft"},
|
||||
description = "Whether to explicitly close the connection after receiving a logout response.")
|
||||
private boolean forceTerminate = false;
|
||||
|
||||
public static void main(String[] args) {
|
||||
EppClient eppClient = new EppClient();
|
||||
JCommander jCommander = new JCommander(eppClient);
|
||||
jCommander.parse(args);
|
||||
if (eppClient.help) {
|
||||
jCommander.usage();
|
||||
return;
|
||||
}
|
||||
eppClient.run();
|
||||
}
|
||||
|
||||
private ImmutableList<String> makeInputList(ZonedDateTime now) {
|
||||
ImmutableList.Builder<String> templatesList = ImmutableList.builder();
|
||||
ImmutableList.Builder<String> inputList = ImmutableList.builder();
|
||||
templatesList.add(readStringFromFile(LOGIN_FILE));
|
||||
templatesList.add(readStringFromFile(LOGOUT_FILE));
|
||||
for (String template : templatesList.build()) {
|
||||
inputList.add(
|
||||
template
|
||||
.replace("@@CLIENT@@", client)
|
||||
.replace("@@PASSWORD@@", password)
|
||||
.replace("@@NOW@@", now.toString()));
|
||||
}
|
||||
return inputList.build();
|
||||
}
|
||||
|
||||
private static String readStringFromFile(String filename) {
|
||||
try {
|
||||
return Resources.toString(getResource(EppClient.class, "resources/" + filename), UTF_8);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalArgumentException("Cannot read from file: resources/" + filename);
|
||||
}
|
||||
}
|
||||
|
||||
private static KeyPair getKeyPair(String filename) throws IOException {
|
||||
byte[] keyBytes = Files.asCharSource(new File(filename), UTF_8).read().getBytes(UTF_8);
|
||||
try {
|
||||
PEMKeyPair pemPair =
|
||||
(PEMKeyPair)
|
||||
new PEMParser(new InputStreamReader(new ByteArrayInputStream(keyBytes), UTF_8))
|
||||
.readObject();
|
||||
return new JcaPEMKeyConverter().setProvider("BC").getKeyPair(pemPair);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static X509Certificate getCertificate(String filename) throws IOException {
|
||||
byte[] certificateBytes = Files.asCharSource(new File(filename), UTF_8).read().getBytes(UTF_8);
|
||||
try {
|
||||
X509CertificateHolder certificateHolder =
|
||||
(X509CertificateHolder)
|
||||
new PEMParser(
|
||||
new InputStreamReader(new ByteArrayInputStream(certificateBytes), UTF_8))
|
||||
.readObject();
|
||||
return new JcaX509CertificateConverter().setProvider("BC").getCertificate(certificateHolder);
|
||||
} catch (IOException | CertificateException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private ChannelInitializer<SocketChannel> makeChannelInitializer(
|
||||
String outputFolder, ImmutableList<ExecutorService> loggingExecutors) throws IOException {
|
||||
return new ChannelInitializer<>() {
|
||||
|
||||
private final ImmutableList<String> inputList =
|
||||
makeInputList(ZonedDateTime.now(ZoneOffset.UTC));
|
||||
private final KeyPair key = getKeyPair(keyFileName);
|
||||
private final X509Certificate cert = getCertificate(certFileName);
|
||||
private final LoggingHandler loggingHandler = new LoggingHandler(LogLevel.INFO);
|
||||
private final EppClientHandler eppClientHandler = new EppClientHandler();
|
||||
|
||||
@Override
|
||||
protected void initChannel(SocketChannel ch) throws Exception {
|
||||
ch.attr(REQUEST_SENT).set(new ArrayList<>());
|
||||
ch.attr(RESPONSE_RECEIVED).set(new ArrayList<>());
|
||||
Path loggingLocation =
|
||||
Paths.get(String.format("%s/%d.log", outputFolder, ch.attr(CHANNEL_NUMBER).get()));
|
||||
ch.attr(LOGGING_LOCATION).set(loggingLocation);
|
||||
ch.attr(FORCE_TERMINATE).set(forceTerminate);
|
||||
ch.attr(LOGGING_EXECUTOR)
|
||||
.set(loggingExecutors.get(ch.attr(CHANNEL_NUMBER).get() % loggingExecutors.size()));
|
||||
|
||||
ch.attr(INPUT_ITERATOR)
|
||||
.set(
|
||||
inputList.stream()
|
||||
.map(
|
||||
(String str) ->
|
||||
str.replace(
|
||||
"@@CHANNEL_NUMBER@@",
|
||||
String.valueOf(ch.attr(CHANNEL_NUMBER).get()))
|
||||
.replace("@@CHANNEL_NUMBER_MODULO@@", String.valueOf(0))
|
||||
.getBytes(UTF_8))
|
||||
.iterator());
|
||||
|
||||
ch.pipeline()
|
||||
.addLast(
|
||||
SslContextBuilder.forClient()
|
||||
.keyManager(key.getPrivate(), cert)
|
||||
.trustManager(InsecureTrustManagerFactory.INSTANCE)
|
||||
.build()
|
||||
.newHandler(ch.alloc(), host.getHostName(), PORT));
|
||||
ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(512 * 1024, 0, 4, -4, 4));
|
||||
ch.pipeline().addLast(new LengthFieldPrepender(4, true));
|
||||
ch.pipeline().addLast(loggingHandler);
|
||||
ch.pipeline().addLast(eppClientHandler);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static String createOutputFolder(String folderName) {
|
||||
Path folder = Paths.get(folderName);
|
||||
if (!folder.toFile().exists()) {
|
||||
folder.toFile().mkdirs();
|
||||
}
|
||||
System.out.printf("\nOutputs saved at %s\n", folder);
|
||||
return folderName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
String outputFolder = createOutputFolder(String.format("load-tests/%s", DateTime.now(UTC)));
|
||||
ImmutableList.Builder<ExecutorService> builder = ImmutableList.builderWithExpectedSize(5);
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
builder.add(Executors.newSingleThreadExecutor());
|
||||
}
|
||||
final ImmutableList<ExecutorService> loggingExecutors = builder.build();
|
||||
|
||||
EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
|
||||
|
||||
try {
|
||||
Bootstrap bootstrap =
|
||||
new Bootstrap()
|
||||
.group(eventLoopGroup)
|
||||
.channel(NioSocketChannel.class)
|
||||
.handler(makeChannelInitializer(outputFolder, loggingExecutors));
|
||||
|
||||
List<ChannelFuture> channelFutures = new ArrayList<>();
|
||||
|
||||
// Three requests: hello (from the proxy), login and logout.
|
||||
int requestPerConnection = 3;
|
||||
|
||||
for (int i = 0; i < connections; i++) {
|
||||
bootstrap.attr(CHANNEL_NUMBER, i);
|
||||
channelFutures.add(
|
||||
bootstrap
|
||||
.connect(host, PORT)
|
||||
.addListener(
|
||||
(ChannelFuture cf) -> {
|
||||
if (!cf.isSuccess()) {
|
||||
System.out.printf("Cannot connect to %s:%s\n", host, PORT);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
LinkedHashSet<Integer> killedConnections = new LinkedHashSet<>();
|
||||
|
||||
// Wait for all channels to close.
|
||||
for (ChannelFuture channelFuture : channelFutures) {
|
||||
Channel channel = channelFuture.syncUninterruptibly().channel();
|
||||
int channelNumber = channel.attr(CHANNEL_NUMBER).get();
|
||||
if (!channel
|
||||
.closeFuture()
|
||||
.awaitUninterruptibly(
|
||||
TIMEOUT_SECONDS * 1000
|
||||
- Duration.between(
|
||||
channel.attr(REQUEST_SENT).get().getFirst(),
|
||||
ZonedDateTime.now(ZoneOffset.UTC))
|
||||
.toMillis())) {
|
||||
channel.close().syncUninterruptibly();
|
||||
killedConnections.add(channelNumber);
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println();
|
||||
System.out.println("====== SUMMARY ======");
|
||||
System.out.printf("Number of connections: %d\n", connections);
|
||||
System.out.printf("Number of requests per connection: %d\n", requestPerConnection);
|
||||
if (!killedConnections.isEmpty()) {
|
||||
System.out.printf("Force killed connections (%d): ", killedConnections.size());
|
||||
for (int channelNumber : killedConnections) {
|
||||
System.out.printf("%d ", channelNumber);
|
||||
}
|
||||
System.out.print("\n");
|
||||
}
|
||||
|
||||
eventLoopGroup.shutdownGracefully();
|
||||
|
||||
channelFutures.forEach(
|
||||
channelFuture -> {
|
||||
channelFuture.channel().attr(LOGGING_REQUEST_COMPLETE).get().syncUninterruptibly();
|
||||
});
|
||||
loggingExecutors.forEach(ExecutorService::shutdown);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
// Copyright 2024 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.client;
|
||||
|
||||
import static google.registry.client.EppClient.CHANNEL_NUMBER;
|
||||
import static google.registry.client.EppClient.FORCE_TERMINATE;
|
||||
import static google.registry.client.EppClient.INPUT_ITERATOR;
|
||||
import static google.registry.client.EppClient.LOGGING_EXECUTOR;
|
||||
import static google.registry.client.EppClient.LOGGING_LOCATION;
|
||||
import static google.registry.client.EppClient.LOGGING_REQUEST_COMPLETE;
|
||||
import static google.registry.client.EppClient.REQUEST_SENT;
|
||||
import static google.registry.client.EppClient.RESPONSE_RECEIVED;
|
||||
import static java.nio.file.StandardOpenOption.APPEND;
|
||||
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelDuplexHandler;
|
||||
import io.netty.channel.ChannelHandler.Sharable;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
import io.netty.util.concurrent.Promise;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
/** Handler that sends EPP requests and receives EPP responses. */
|
||||
@SuppressWarnings("FutureReturnValueIgnored")
|
||||
@Sharable
|
||||
public class EppClientHandler extends ChannelDuplexHandler {
|
||||
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
|
||||
static class FileWriter implements Runnable {
|
||||
|
||||
private final Path loggingLocation;
|
||||
private final byte[] contents;
|
||||
private final ZonedDateTime time;
|
||||
|
||||
FileWriter(Path loggingLocation, byte[] contents, ZonedDateTime time) {
|
||||
this.loggingLocation = loggingLocation;
|
||||
this.contents = contents;
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (!Files.exists(loggingLocation)) {
|
||||
Files.createFile(loggingLocation);
|
||||
}
|
||||
Files.writeString(loggingLocation, time.toString() + "\n", APPEND);
|
||||
Files.write(loggingLocation, contents, APPEND);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
|
||||
ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
|
||||
ctx.channel().attr(REQUEST_SENT).get().add(now);
|
||||
ctx.channel().attr(LOGGING_REQUEST_COMPLETE).set(ctx.executor().newPromise());
|
||||
super.channelRegistered(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||
Promise<Void> loggingCompletePromise = ctx.channel().attr(LOGGING_REQUEST_COMPLETE).get();
|
||||
if (!loggingCompletePromise.isDone()) {
|
||||
loggingCompletePromise.setSuccess(null);
|
||||
}
|
||||
logger.atWarning().withCause(cause).log(
|
||||
"Connection %d closed.", ctx.channel().attr(CHANNEL_NUMBER).get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) {
|
||||
ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
|
||||
Channel ch = ctx.channel();
|
||||
ctx.channel().attr(RESPONSE_RECEIVED).get().add(now);
|
||||
if (msg instanceof ByteBuf buffer) {
|
||||
byte[] contents = new byte[buffer.readableBytes()];
|
||||
buffer.readBytes(contents);
|
||||
ReferenceCountUtil.release(buffer);
|
||||
if (ch.attr(LOGGING_LOCATION).get() != null) {
|
||||
ch.attr(LOGGING_EXECUTOR)
|
||||
.get()
|
||||
.submit(new FileWriter(ch.attr(LOGGING_LOCATION).get(), contents, now));
|
||||
}
|
||||
if (ch.attr(INPUT_ITERATOR).get().hasNext()) {
|
||||
ch.writeAndFlush(ch.attr(INPUT_ITERATOR).get().next());
|
||||
} else {
|
||||
ch.attr(LOGGING_REQUEST_COMPLETE).get().setSuccess(null);
|
||||
if (ch.attr(FORCE_TERMINATE).get()) {
|
||||
ch.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
|
||||
ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
|
||||
Channel ch = ctx.channel();
|
||||
ctx.channel().attr(REQUEST_SENT).get().add(now);
|
||||
if (msg instanceof byte[] outputBytes) {
|
||||
ByteBuf buffer = Unpooled.buffer();
|
||||
buffer.writeBytes(outputBytes);
|
||||
ctx.write(buffer, promise);
|
||||
if (ch.attr(LOGGING_LOCATION).get() != null) {
|
||||
ch.attr(LOGGING_EXECUTOR)
|
||||
.get()
|
||||
.submit(new FileWriter(ch.attr(LOGGING_LOCATION).get(), outputBytes, now));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
|
||||
Promise<Void> loggingCompletePromise = ctx.channel().attr(LOGGING_REQUEST_COMPLETE).get();
|
||||
if (!loggingCompletePromise.isDone()) {
|
||||
loggingCompletePromise.setSuccess(null);
|
||||
}
|
||||
super.close(ctx, promise);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||
Promise<Void> loggingCompletePromise = ctx.channel().attr(LOGGING_REQUEST_COMPLETE).get();
|
||||
if (!loggingCompletePromise.isDone()) {
|
||||
loggingCompletePromise.setSuccess(null);
|
||||
}
|
||||
super.channelInactive(ctx);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
## EPP Load Testing Client
|
||||
|
||||
This project contains an EPP client that can be use for load testing the full
|
||||
registry platform. All the below commands should be run from the merged root.
|
||||
|
||||
### Setting up the test instances
|
||||
|
||||
* If you have not done s yet, you will need to set up ssh keys in your
|
||||
[GCE metadata](https://pantheon.corp.google.com/compute/metadata?resourceTab=sshkeys):
|
||||
|
||||
* To create however many GCE instances you want to run on, modify the
|
||||
`instanceSetUp.sh` file to include the correct number of instances.
|
||||
|
||||
* Run the instance set up script to create and configure each of the GCE
|
||||
instances to be used for load testing:
|
||||
|
||||
```shell
|
||||
$ load-testing/instanceSetUp.sh
|
||||
```
|
||||
|
||||
* Verify that the IP address of any created instances is in the allowlist of the
|
||||
proxy registrar user.
|
||||
* Use the below command to get the IP addresses of the created instances.
|
||||
|
||||
```shell
|
||||
$ (gcloud compute instances list | awk '/^loadtest/ { print $5 }')
|
||||
```
|
||||
|
||||
* Check the proxy registrar's current allow list
|
||||
|
||||
```shell
|
||||
$ nomulus -e sandbox get_registrar proxy | grep ipAddressAllowList
|
||||
```
|
||||
|
||||
* All of your host ip addresses should match a netmask specified in the proxy
|
||||
allow list. If not, you'll need to redefine the list:
|
||||
|
||||
```shell
|
||||
$ nomulus -e sandbox update_registrar proxy --ip_allow_list=<new-comma-separated-allowlist>
|
||||
```
|
||||
|
||||
|
||||
### Running the client
|
||||
|
||||
* From the merged root build the load testing client:
|
||||
```shell
|
||||
$ ./nom_build :load-testing:buildLoadTestClient
|
||||
```
|
||||
|
||||
* Deploy the client to the GCE instances (this will create a local staging
|
||||
directory and deploy it to each of your previously created loadtest GCE instances):
|
||||
```shell
|
||||
$ ./nom_build :load-testing:deployLoadTestsToInstances
|
||||
```
|
||||
|
||||
* Run the load test. Configurations of the load test can be made by configuring
|
||||
this `run.sh` file locally.
|
||||
|
||||
```shell
|
||||
$ load-testing/run.sh
|
||||
```
|
||||
|
||||
### Cleanup
|
||||
|
||||
* Run the instance clean up script to delete the created instances
|
||||
|
||||
```shell
|
||||
$ load-testing/instanceCleanUp.sh
|
||||
```
|
||||
|
||||
* You may want to remove any host key fingerprints for those hosts from your ~/.ssh/known_hosts file (these IPs tend to get reused with new host keys)
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<login>
|
||||
<clID>@@CLIENT@@</clID>
|
||||
<pw>@@PASSWORD@@</pw>
|
||||
<options>
|
||||
<version>1.0</version>
|
||||
<lang>en</lang>
|
||||
</options>
|
||||
<svcs>
|
||||
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
|
||||
</svcs>
|
||||
</login>
|
||||
<clTRID>epp-client-login-@@NOW@@-@@CHANNEL_NUMBER@@</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<logout/>
|
||||
<clTRID>epp-client-logout-@@NOW@@-@@CHANNEL_NUMBER@@</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
@@ -47,3 +47,4 @@ include 'services:tools'
|
||||
include 'services:pubapi'
|
||||
include 'console-webapp'
|
||||
include 'jetty'
|
||||
include 'load-testing'
|
||||
|
||||
@@ -57,6 +57,16 @@ public class GcpJsonFormatter extends Formatter {
|
||||
/** JSON field that contains the content, this will show up as the main entry in a log. */
|
||||
private static final String MESSAGE = "message";
|
||||
|
||||
/**
|
||||
* JSON field that contains the stack trace, if any.
|
||||
*
|
||||
* <p>Note that this field is not part of the structured logging that stackdriver understands.
|
||||
* Normally we'd just append the stack trace to the message itself. However, for unclear reasons,
|
||||
* if we do that on GKE, the log entry containing a stack trace will be lumped together with
|
||||
* several following log entries and makes it hard to read.
|
||||
*/
|
||||
private static final String STACKTRACE = "stacktrace";
|
||||
|
||||
private static final String FILE = "file";
|
||||
|
||||
private static final String FUNCTION = "function";
|
||||
@@ -99,16 +109,17 @@ public class GcpJsonFormatter extends Formatter {
|
||||
String severity = severityFor(record.getLevel());
|
||||
|
||||
// The rest is mostly lifted from java.util.logging.SimpleFormatter.
|
||||
String stacktrace = "";
|
||||
String throwable = "";
|
||||
if (record.getThrown() != null) {
|
||||
StringWriter sw = new StringWriter();
|
||||
try (PrintWriter pw = new PrintWriter(sw)) {
|
||||
pw.println();
|
||||
record.getThrown().printStackTrace(pw);
|
||||
}
|
||||
stacktrace = sw.toString();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
pw.println();
|
||||
record.getThrown().printStackTrace(pw);
|
||||
pw.close();
|
||||
throwable = sw.toString();
|
||||
}
|
||||
String message = '\n' + record.getMessage() + stacktrace;
|
||||
|
||||
String message = '\n' + formatMessage(record);
|
||||
|
||||
String function = "";
|
||||
if (record.getSourceClassName() != null) {
|
||||
@@ -144,6 +155,9 @@ public class GcpJsonFormatter extends Formatter {
|
||||
json.put(SEVERITY, severity);
|
||||
json.put(SOURCE_LOCATION, sourceLocation);
|
||||
json.put(MESSAGE, message);
|
||||
if (!throwable.isEmpty()) {
|
||||
json.put(STACKTRACE, throwable);
|
||||
}
|
||||
if (traceId.get() != null) {
|
||||
json.put(TRACE, traceId.get());
|
||||
}
|
||||
|
||||
@@ -109,14 +109,11 @@ class GcpJsonFormatterTest {
|
||||
handler.close();
|
||||
String output = ostream.toString(StandardCharsets.US_ASCII);
|
||||
String prefix =
|
||||
makeJson(
|
||||
"ERROR",
|
||||
108,
|
||||
"testSuccess_withCause",
|
||||
"Something went terribly wrong\\njava.lang.RuntimeException: boom!");
|
||||
// Remove the last three characters (", }, \n) from the template as the actual output contains
|
||||
makeJson("ERROR", 108, "testSuccess_withCause", "Something went terribly wrong");
|
||||
// Remove the last two characters (}, \n) from the template as the actual output contains
|
||||
// the full stack trace.
|
||||
prefix = prefix.substring(0, prefix.length() - 3);
|
||||
prefix = prefix.substring(0, prefix.length() - 2);
|
||||
prefix += ",\"stacktrace\":\"\\njava.lang.RuntimeException: boom!\\n";
|
||||
assertThat(output).startsWith(prefix);
|
||||
}
|
||||
|
||||
@@ -126,14 +123,11 @@ class GcpJsonFormatterTest {
|
||||
handler.close();
|
||||
String output = ostream.toString(StandardCharsets.US_ASCII);
|
||||
String prefix =
|
||||
makeJson(
|
||||
"ERROR",
|
||||
125,
|
||||
"testSuccess_withStackTrace",
|
||||
"Something is worth checking\\ncom.google.common.flogger.LogSiteStackTrace: FULL");
|
||||
// Remove the last three characters (", }, \n) from the template as the actual output contains
|
||||
makeJson("ERROR", 122, "testSuccess_withStackTrace", "Something is worth checking");
|
||||
// Remove the last three characters (}, \n) from the template as the actual output contains
|
||||
// the full stack trace.
|
||||
prefix = prefix.substring(0, prefix.length() - 3);
|
||||
prefix = prefix.substring(0, prefix.length() - 2);
|
||||
prefix += ",\"stacktrace\":\"\\ncom.google.common.flogger.LogSiteStackTrace: FULL\\n";
|
||||
assertThat(output).startsWith(prefix);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user