From 0d135e2c8ab46f3c35ce4863ae07360900138d6e Mon Sep 17 00:00:00 2001 From: Harshita Sharma Date: Tue, 5 Aug 2025 06:15:28 +0000 Subject: [PATCH 01/12] Fix: Robustly parse certs and provide specific errors --- .../registry/ui/server/console/settings/SecurityAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/google/registry/ui/server/console/settings/SecurityAction.java b/core/src/main/java/google/registry/ui/server/console/settings/SecurityAction.java index 80341d567ef..1bb00146793 100644 --- a/core/src/main/java/google/registry/ui/server/console/settings/SecurityAction.java +++ b/core/src/main/java/google/registry/ui/server/console/settings/SecurityAction.java @@ -120,7 +120,7 @@ private void setResponse(Registrar savedRegistrar) { } } } catch (InsecureCertificateException e) { - setFailedResponse("Invalid certificate in parameter", SC_BAD_REQUEST); + setFailedResponse(e.getMessage(), SC_BAD_REQUEST); return; } From c0bc0279e08c8fa636a796e274d4333c653340a0 Mon Sep 17 00:00:00 2001 From: Harshita Sharma Date: Wed, 6 Aug 2025 10:35:52 +0000 Subject: [PATCH 02/12] Add test for expired certificate failure --- .../console/settings/SecurityActionTest.java | 43 +++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java b/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java index 350a8e944c6..1d43b1c6d02 100644 --- a/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java +++ b/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java @@ -4,7 +4,7 @@ // 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 +//      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, @@ -20,6 +20,7 @@ import static google.registry.testing.DatabaseHelper.loadSingleton; import static google.registry.testing.SqlHelper.saveRegistrar; import static google.registry.util.DateTimeUtils.START_OF_TIME; +import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST; import static jakarta.servlet.http.HttpServletResponse.SC_OK; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.when; @@ -54,6 +55,24 @@ class SecurityActionTest extends ConsoleActionBaseTestCase { SAMPLE_CERT2); private Registrar testRegistrar; + private static final String EXPIRED_CERT_PEM = + "-----BEGIN CERTIFICATE-----\\n" + + "MIIC/jCCAmQCCQD3249g9Nl9aTANBgkqhkiG9w0BAQsFADCBjjELMAkGA1UEBhMC\\n" + + "VVMxETAPBgNVBAgMCENhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28x\\n" + + "GTAXBgNVBAoMEEJhZFNzbCwgSW5jLjogQ0ExGTAXBgNVBAsMEEJhZFNzbCwgSW5j\\n" + + "LjogQ0ExGTAXBgNVBAMMEGJhZHNzbC5jb206IENBMQswCQYDVQQGEwJVUzAeFw0x\\n" + + "NTAyMjAxODQ1NTVaFw0xNTAyMjUxODQ1NTVaMIGAMQswCQYDVQQGEwJVUzERMA8G\\n" + + "A1UECAwIQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEaMBgGA1UE\\n" + + "CgwRQmFkU3NsLCBJbmMuOiBFQzEYMBYGA1UEAwwPKiouZXhwaXJlZC5iYWRzc2wx\\n" + + "CzAJBgNVBAYTAlVTMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDP532p2L8V\\n" + + "/x02y5I65e3FbfiM85v63j2f9Jd9C17C0WKkAmvRFCjQ8q2PcyX2z6vi/pG4ZveG\\n" + + "L6Rjxf4u3V4h3cM3Wns2e4hFitN2aA4s2sJ3aPSlXgP9PN6A+Lwusnfk11n+r5wS\\n" + + "gT3y5xJNL9x2YyLgGz8iE2fV9j1R1wIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAK\\n" + + "M/Q0GfLzozlwpi5iUSz/dcf4S/2ssUnRzkmvfVl4/NCwM95pB2fr6vM6Sc0vB3pC\\n" + + "nQ5NtVl4jI5qgC7NaI6bT8G2n48zI9b4ks4Kixb3eU6y3V5L0asIdC2XAPd/n2dg\\n" + + "x1sA81Yd368p36LhXXF0Q2v33qT8Z3s=\\n" + + "-----END CERTIFICATE-----"; + private AuthenticatedRegistrarAccessor registrarAccessor = AuthenticatedRegistrarAccessor.createForTesting( ImmutableSetMultimap.of("registrarId", AuthenticatedRegistrarAccessor.Role.ADMIN)); @@ -90,9 +109,23 @@ void testSuccess_postRegistrarInfo() throws IOException { assertThat(history.getDescription()).hasValue("registrarId|IP_CHANGE,PRIMARY_SSL_CERT_CHANGE"); } - private SecurityAction createAction(String registrarId) throws IOException { + @Test + void testFailure_expiredCertificate_returnsSpecificError() throws IOException { + String jsonWithBadCert = + String.format( + "{\"registrarId\": \"registrarId\", \"clientCertificate\": \"%s\"}", EXPIRED_CERT_PEM); + SecurityAction action = createAction(testRegistrar.getRegistrarId(), jsonWithBadCert); + + action.run(); + + FakeResponse response = (FakeResponse) consoleApiParams.response(); + assertThat(response.getStatus()).isEqualTo(SC_BAD_REQUEST); + assertThat(response.getPayload()).isEqualTo("Certificate is expired."); + } + + private SecurityAction createAction(String registrarId, String jsonBody) throws IOException { when(consoleApiParams.request().getMethod()).thenReturn(Action.Method.POST.toString()); - doReturn(new BufferedReader(new StringReader(jsonRegistrar1))) + doReturn(new BufferedReader(new StringReader(jsonBody))) .when(consoleApiParams.request()) .getReader(); Optional maybeRegistrar = @@ -101,4 +134,8 @@ private SecurityAction createAction(String registrarId) throws IOException { return new SecurityAction( consoleApiParams, certificateChecker, registrarAccessor, registrarId, maybeRegistrar); } + + private SecurityAction createAction(String registrarId) throws IOException { + return createAction(registrarId, jsonRegistrar1); + } } From 5c2e23100c24d52e318a7b06bbe721f1f03b2a94 Mon Sep 17 00:00:00 2001 From: Harshita Sharma Date: Wed, 6 Aug 2025 10:38:27 +0000 Subject: [PATCH 03/12] fixing indentation --- .../registry/ui/server/console/settings/SecurityActionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java b/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java index 1d43b1c6d02..b7dcd5276dc 100644 --- a/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java +++ b/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java @@ -4,7 +4,7 @@ // 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 +//     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, From 83991fa3259125ec6444b3fbeb5d1e05e7d2f122 Mon Sep 17 00:00:00 2001 From: Harshita Sharma Date: Wed, 6 Aug 2025 10:39:56 +0000 Subject: [PATCH 04/12] fixing indentation --- .../registry/ui/server/console/settings/SecurityActionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java b/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java index b7dcd5276dc..7be1310e027 100644 --- a/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java +++ b/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java @@ -4,7 +4,7 @@ // 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 +// 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, From 8fae2239b5aced32d7e9c69f26e0fd9e89e1239f Mon Sep 17 00:00:00 2001 From: sharma1210 Date: Thu, 7 Aug 2025 15:53:42 +0530 Subject: [PATCH 05/12] Update SecurityActionTest.java --- .../registry/ui/server/console/settings/SecurityActionTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java b/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java index 7be1310e027..69427bb6e52 100644 --- a/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java +++ b/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java @@ -111,6 +111,7 @@ void testSuccess_postRegistrarInfo() throws IOException { @Test void testFailure_expiredCertificate_returnsSpecificError() throws IOException { + clock.setTo(DateTime.parse("2020-01-01T00:00:00Z")); String jsonWithBadCert = String.format( "{\"registrarId\": \"registrarId\", \"clientCertificate\": \"%s\"}", EXPIRED_CERT_PEM); From d980aa93633b8022ae5a14671b37e6f75cd86f99 Mon Sep 17 00:00:00 2001 From: sharma1210 Date: Thu, 7 Aug 2025 19:50:17 +0530 Subject: [PATCH 06/12] Update SecurityActionTest.java for correcting the testcase --- .../console/settings/SecurityActionTest.java | 74 +++++++++++++------ 1 file changed, 52 insertions(+), 22 deletions(-) diff --git a/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java b/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java index 69427bb6e52..03dc8f0fc1e 100644 --- a/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java +++ b/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java @@ -55,22 +55,27 @@ class SecurityActionTest extends ConsoleActionBaseTestCase { SAMPLE_CERT2); private Registrar testRegistrar; - private static final String EXPIRED_CERT_PEM = - "-----BEGIN CERTIFICATE-----\\n" - + "MIIC/jCCAmQCCQD3249g9Nl9aTANBgkqhkiG9w0BAQsFADCBjjELMAkGA1UEBhMC\\n" - + "VVMxETAPBgNVBAgMCENhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28x\\n" - + "GTAXBgNVBAoMEEJhZFNzbCwgSW5jLjogQ0ExGTAXBgNVBAsMEEJhZFNzbCwgSW5j\\n" - + "LjogQ0ExGTAXBgNVBAMMEGJhZHNzbC5jb206IENBMQswCQYDVQQGEwJVUzAeFw0x\\n" - + "NTAyMjAxODQ1NTVaFw0xNTAyMjUxODQ1NTVaMIGAMQswCQYDVQQGEwJVUzERMA8G\\n" - + "A1UECAwIQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEaMBgGA1UE\\n" - + "CgwRQmFkU3NsLCBJbmMuOiBFQzEYMBYGA1UEAwwPKiouZXhwaXJlZC5iYWRzc2wx\\n" - + "CzAJBgNVBAYTAlVTMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDP532p2L8V\\n" - + "/x02y5I65e3FbfiM85v63j2f9Jd9C17C0WKkAmvRFCjQ8q2PcyX2z6vi/pG4ZveG\\n" - + "L6Rjxf4u3V4h3cM3Wns2e4hFitN2aA4s2sJ3aPSlXgP9PN6A+Lwusnfk11n+r5wS\\n" - + "gT3y5xJNL9x2YyLgGz8iE2fV9j1R1wIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAK\\n" - + "M/Q0GfLzozlwpi5iUSz/dcf4S/2ssUnRzkmvfVl4/NCwM95pB2fr6vM6Sc0vB3pC\\n" - + "nQ5NtVl4jI5qgC7NaI6bT8G2n48zI9b4ks4Kixb3eU6y3V5L0asIdC2XAPd/n2dg\\n" - + "x1sA81Yd368p36LhXXF0Q2v33qT8Z3s=\\n" + private static final String VALIDITY_TOO_LONG_CERT_PEM = + "-----BEGIN CERTIFICATE-----\n" + + "MIIDejCCAv+gAwIBAgIQHNcSEt4VENkSgtozEEoQLzAKBggqhkjOPQQDAzB8MQsw\n" + + "CQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0b24xGDAW\n" + + "BgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBSb290IENl\n" + + "cnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzAeFw0xOTAzMDcxOTQyNDJaFw0zNDAz\n" + + "MDMxOTQyNDJaMG8xCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UE\n" + + "BwwHSG91c3RvbjERMA8GA1UECgwIU1NMIENvcnAxKzApBgNVBAMMIlNTTC5jb20g\n" + + "U1NMIEludGVybWVkaWF0ZSBDQSBFQ0MgUjIwdjAQBgcqhkjOPQIBBgUrgQQAIgNi\n" + + "AASEOWn30uEYKDLFu4sCjFQ1VupFaeMtQjqVWyWSA7+KFljnsVaFQ2hgs4cQk1f/\n" + + "RQ2INSwdVCYU0i5qsbom20rigUhDh9dM/r6bEZ75eFE899kSCI14xqThYVLPdLEl\n" + + "+dyjggFRMIIBTTASBgNVHRMBAf8ECDAGAQH/AgEAMB8GA1UdIwQYMBaAFILRhXMw\n" + + "5zUE044CkvvlpNHEIejNMHgGCCsGAQUFBwEBBGwwajBGBggrBgEFBQcwAoY6aHR0\n" + + "cDovL3d3dy5zc2wuY29tL3JlcG9zaXRvcnkvU1NMY29tLVJvb3RDQS1FQ0MtMzg0\n" + + "LVIxLmNydDAgBggrBgEFBQcwAYYUaHR0cDovL29jc3BzLnNzbC5jb20wEQYDVR0g\n" + + "BAowCDAGBgRVHSAAMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATA7BgNV\n" + + "HR8ENDAyMDCgLqAshipodHRwOi8vY3Jscy5zc2wuY29tL3NzbC5jb20tZWNjLVJv\n" + + "b3RDQS5jcmwwHQYDVR0OBBYEFA10Zgpen+Is7NXCXSUEf3Uyuv99MA4GA1UdDwEB\n" + + "/wQEAwIBhjAKBggqhkjOPQQDAwNpADBmAjEAxYt6Ylk/N8Fch/3fgKYKwI5A011Q\n" + + "MKW0h3F9JW/NX/F7oYtWrxljheH8n2BrkDybAjEAlCxkLE0vQTYcFzrR24oogyw6\n" + + "VkgTm92+jiqJTO5SSA9QUa092S5cTKiHkH2cOM6m\n" + "-----END CERTIFICATE-----"; private AuthenticatedRegistrarAccessor registrarAccessor = @@ -109,19 +114,44 @@ void testSuccess_postRegistrarInfo() throws IOException { assertThat(history.getDescription()).hasValue("registrarId|IP_CHANGE,PRIMARY_SSL_CERT_CHANGE"); } - @Test - void testFailure_expiredCertificate_returnsSpecificError() throws IOException { - clock.setTo(DateTime.parse("2020-01-01T00:00:00Z")); +@Test + void testFailure_validityPeriodTooLong_returnsSpecificError() throws IOException { + CertificateChecker strictChecker = + new CertificateChecker( + ImmutableSortedMap.of(START_OF_TIME, 398), + 30, + 15, + 2048, + ImmutableSet.of("secp256r1", "secp384r1"), + clock); + + clock.setTo(DateTime.parse("2025-01-01T00:00:00Z")); + String escapedCert = VALIDITY_TOO_LONG_CERT_PEM.replace("\n", "\\n"); String jsonWithBadCert = String.format( - "{\"registrarId\": \"registrarId\", \"clientCertificate\": \"%s\"}", EXPIRED_CERT_PEM); - SecurityAction action = createAction(testRegistrar.getRegistrarId(), jsonWithBadCert); + "{\"registrarId\": \"registrarId\", \"clientCertificate\": \"%s\"}", escapedCert); + when(consoleApiParams.request().getMethod()).thenReturn(Action.Method.POST.toString()); + doReturn(new BufferedReader(new StringReader(jsonWithBadCert))) + .when(consoleApiParams.request()) + .getReader(); + Optional maybeRegistrar = + ConsoleModule.provideRegistrar( + GSON, RequestModule.provideJsonBody(consoleApiParams.request(), GSON)); + SecurityAction action = + new SecurityAction( + consoleApiParams, + strictChecker, + registrarAccessor, + testRegistrar.getRegistrarId(), + maybeRegistrar); action.run(); + String expectedError = + "Certificate validity period is too long; it must be less than or equal to 398 days."; FakeResponse response = (FakeResponse) consoleApiParams.response(); assertThat(response.getStatus()).isEqualTo(SC_BAD_REQUEST); - assertThat(response.getPayload()).isEqualTo("Certificate is expired."); + assertThat(response.getPayload()).isEqualTo(expectedError); } private SecurityAction createAction(String registrarId, String jsonBody) throws IOException { From 7108b83e1e03dd1b65d3f71e2ed65318c76d08ad Mon Sep 17 00:00:00 2001 From: Harshita Sharma Date: Thu, 7 Aug 2025 16:07:20 +0000 Subject: [PATCH 07/12] Fix: Provide indentation fix --- .../ui/server/console/settings/SecurityActionTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java b/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java index 03dc8f0fc1e..bd08e626899 100644 --- a/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java +++ b/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java @@ -114,11 +114,11 @@ void testSuccess_postRegistrarInfo() throws IOException { assertThat(history.getDescription()).hasValue("registrarId|IP_CHANGE,PRIMARY_SSL_CERT_CHANGE"); } -@Test + @Test void testFailure_validityPeriodTooLong_returnsSpecificError() throws IOException { CertificateChecker strictChecker = new CertificateChecker( - ImmutableSortedMap.of(START_OF_TIME, 398), + ImmutableSortedMap.of(START_OF_TIME, 398), 30, 15, 2048, @@ -141,7 +141,7 @@ void testFailure_validityPeriodTooLong_returnsSpecificError() throws IOException SecurityAction action = new SecurityAction( consoleApiParams, - strictChecker, + strictChecker, registrarAccessor, testRegistrar.getRegistrarId(), maybeRegistrar); From 411c4bdfb0789314cd628950f5f2ce98daacfb95 Mon Sep 17 00:00:00 2001 From: Harshita Sharma Date: Fri, 8 Aug 2025 16:47:14 +0000 Subject: [PATCH 08/12] Fixing Deduplication in test --- .../console/settings/SecurityActionTest.java | 46 ++++++++----------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java b/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java index bd08e626899..0e328dfb89f 100644 --- a/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java +++ b/core/src/test/java/google/registry/ui/server/console/settings/SecurityActionTest.java @@ -82,26 +82,25 @@ class SecurityActionTest extends ConsoleActionBaseTestCase { AuthenticatedRegistrarAccessor.createForTesting( ImmutableSetMultimap.of("registrarId", AuthenticatedRegistrarAccessor.Role.ADMIN)); - private CertificateChecker certificateChecker = - new CertificateChecker( - ImmutableSortedMap.of(START_OF_TIME, 20825, DateTime.parse("2020-09-01T00:00:00Z"), 398), - 30, - 15, - 2048, - ImmutableSet.of("secp256r1", "secp384r1"), - clock); @BeforeEach void beforeEach() { testRegistrar = saveRegistrar("registrarId"); } - @Test void testSuccess_postRegistrarInfo() throws IOException { + CertificateChecker lenientChecker = + new CertificateChecker( + ImmutableSortedMap.of( + START_OF_TIME, 20825, DateTime.parse("2020-09-01T00:00:00Z"), 398), + 30, + 15, + 2048, + ImmutableSet.of("secp256r1", "secp384r1"), + clock); + clock.setTo(DateTime.parse("2020-11-01T00:00:00Z")); - SecurityAction action = - createAction( - testRegistrar.getRegistrarId()); + SecurityAction action = createAction(testRegistrar.getRegistrarId(), lenientChecker); action.run(); assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_OK); Registrar r = loadRegistrar(testRegistrar.getRegistrarId()); @@ -131,20 +130,8 @@ void testFailure_validityPeriodTooLong_returnsSpecificError() throws IOException String.format( "{\"registrarId\": \"registrarId\", \"clientCertificate\": \"%s\"}", escapedCert); - when(consoleApiParams.request().getMethod()).thenReturn(Action.Method.POST.toString()); - doReturn(new BufferedReader(new StringReader(jsonWithBadCert))) - .when(consoleApiParams.request()) - .getReader(); - Optional maybeRegistrar = - ConsoleModule.provideRegistrar( - GSON, RequestModule.provideJsonBody(consoleApiParams.request(), GSON)); SecurityAction action = - new SecurityAction( - consoleApiParams, - strictChecker, - registrarAccessor, - testRegistrar.getRegistrarId(), - maybeRegistrar); + createAction(testRegistrar.getRegistrarId(), jsonWithBadCert, strictChecker); action.run(); String expectedError = @@ -154,7 +141,9 @@ void testFailure_validityPeriodTooLong_returnsSpecificError() throws IOException assertThat(response.getPayload()).isEqualTo(expectedError); } - private SecurityAction createAction(String registrarId, String jsonBody) throws IOException { + private SecurityAction createAction( + String registrarId, String jsonBody, CertificateChecker certificateChecker) + throws IOException { when(consoleApiParams.request().getMethod()).thenReturn(Action.Method.POST.toString()); doReturn(new BufferedReader(new StringReader(jsonBody))) .when(consoleApiParams.request()) @@ -166,7 +155,8 @@ private SecurityAction createAction(String registrarId, String jsonBody) throws consoleApiParams, certificateChecker, registrarAccessor, registrarId, maybeRegistrar); } - private SecurityAction createAction(String registrarId) throws IOException { - return createAction(registrarId, jsonRegistrar1); + private SecurityAction createAction(String registrarId, CertificateChecker certificateChecker) + throws IOException { + return createAction(registrarId, jsonRegistrar1, certificateChecker); } } From aa7330a451dc1f46bf882480be3b16f9634c3a94 Mon Sep 17 00:00:00 2001 From: Harshita Sharma Date: Wed, 8 Oct 2025 17:48:48 +0000 Subject: [PATCH 09/12] Add detailed logging to ConsoleApiAction for debugging --- .../google/registry/ui/server/console/ConsoleApiAction.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/main/java/google/registry/ui/server/console/ConsoleApiAction.java b/core/src/main/java/google/registry/ui/server/console/ConsoleApiAction.java index c244adca4bb..3fa60f33b9c 100644 --- a/core/src/main/java/google/registry/ui/server/console/ConsoleApiAction.java +++ b/core/src/main/java/google/registry/ui/server/console/ConsoleApiAction.java @@ -75,6 +75,8 @@ public ConsoleApiAction(ConsoleApiParams consoleApiParams) { public final void run() { // Shouldn't be even possible because of Auth annotations on the various implementing classes if (consoleApiParams.authResult().user().isEmpty()) { + logger.atWarning().log("harshta User object is empty, failing with UNAUTHORIZED."); + logger.atWarning().log("harshita logs ",consoleApiParams.authResult()); consoleApiParams.response().setStatus(SC_UNAUTHORIZED); return; } From 14556f67b56554f903f37429113b9d09687ad949 Mon Sep 17 00:00:00 2001 From: Harshita Sharma Date: Wed, 8 Oct 2025 18:09:48 +0000 Subject: [PATCH 10/12] Add detailed logging to ConsoleApiAction for debugging1 --- .../google/registry/ui/server/console/ConsoleApiAction.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/google/registry/ui/server/console/ConsoleApiAction.java b/core/src/main/java/google/registry/ui/server/console/ConsoleApiAction.java index 3fa60f33b9c..c1357130c16 100644 --- a/core/src/main/java/google/registry/ui/server/console/ConsoleApiAction.java +++ b/core/src/main/java/google/registry/ui/server/console/ConsoleApiAction.java @@ -76,7 +76,7 @@ public final void run() { // Shouldn't be even possible because of Auth annotations on the various implementing classes if (consoleApiParams.authResult().user().isEmpty()) { logger.atWarning().log("harshta User object is empty, failing with UNAUTHORIZED."); - logger.atWarning().log("harshita logs ",consoleApiParams.authResult()); + logger.atInfo().log("harshita logs: %s", consoleApiParams.authResult()); consoleApiParams.response().setStatus(SC_UNAUTHORIZED); return; } @@ -213,7 +213,8 @@ protected void sendExternalUpdates( The following changes were made in registry %s environment to the registrar %s by\ %s: - %s""", + %s\ + """, environment, registrar.getRegistrarId(), consoleApiParams.authResult().userIdForLogging(), From 7609d4da2de20f38648be919633e0f004de77761 Mon Sep 17 00:00:00 2001 From: Harshita Sharma Date: Wed, 8 Oct 2025 20:28:00 +0000 Subject: [PATCH 11/12] Add detailed logging to ConsoleApiAction for debugging1 --- .../google/registry/ui/server/console/ConsoleApiAction.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/main/java/google/registry/ui/server/console/ConsoleApiAction.java b/core/src/main/java/google/registry/ui/server/console/ConsoleApiAction.java index c1357130c16..bc893245310 100644 --- a/core/src/main/java/google/registry/ui/server/console/ConsoleApiAction.java +++ b/core/src/main/java/google/registry/ui/server/console/ConsoleApiAction.java @@ -74,6 +74,10 @@ public ConsoleApiAction(ConsoleApiParams consoleApiParams) { @Override public final void run() { // Shouldn't be even possible because of Auth annotations on the various implementing classes + logger.atInfo().log("Har AuthResult received in ConsoleApiAction."); + logger.atInfo().log("Har AuthLevel: %s", consoleApiParams.authResult().authLevel()); + logger.atInfo().log("User object: %s", consoleApiParams.authResult().user()); + logger.atInfo().log("ServiceAccountEmail: %s", consoleApiParams.authResult().serviceAccountEmail()); if (consoleApiParams.authResult().user().isEmpty()) { logger.atWarning().log("harshta User object is empty, failing with UNAUTHORIZED."); logger.atInfo().log("harshita logs: %s", consoleApiParams.authResult()); From f97bbe167c486e2dadc9a74381913be6a2f994bb Mon Sep 17 00:00:00 2001 From: Harshita Sharma Date: Thu, 6 Nov 2025 15:03:13 +0000 Subject: [PATCH 12/12] test --- .../registry/tools/RdapQueryCommand.java | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 core/src/main/java/google/registry/tools/RdapQueryCommand.java diff --git a/core/src/main/java/google/registry/tools/RdapQueryCommand.java b/core/src/main/java/google/registry/tools/RdapQueryCommand.java new file mode 100644 index 00000000000..0e164bea16c --- /dev/null +++ b/core/src/main/java/google/registry/tools/RdapQueryCommand.java @@ -0,0 +1,71 @@ +package google.registry.tools; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import com.google.common.collect.ImmutableSet; +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import java.util.List; +import java.util.Map; + +/** Command to execute an authenticated RDAP query. */ +@Parameters(separators = " =", commandDescription = "Manually perform an authenticated RDAP query") +public final class RdapQueryCommand implements CommandWithConnection { + + private static final ImmutableSet VALID_TYPES = + ImmutableSet.of("domain", "nameserver", "entity"); + + @Parameter( + description = "RDAP query string, in the format ", + required = true) + private List mainParameters; + + private Connection connection; + + @Override + public void setConnection(Connection connection) { + this.connection = connection; + } + + @Override + public void run() throws Exception { + if (mainParameters.size() != 2) { + throw new IllegalArgumentException("Expected 2 arguments: "); + } + String type = mainParameters.get(0).toLowerCase(); + if (!VALID_TYPES.contains(type)) { + throw new IllegalArgumentException( + String.format("Invalid object type '%s'. Must be one of %s", type, VALID_TYPES)); + } + String name = mainParameters.get(1); + String path = String.format("/rdap/%s/%s", type, name); + + // Use the connection object to make an authenticated GET request. + String rdapResponse = connection.sendGetRequest(path); + + // Parse and format the JSON response. + JsonElement rdapJson = new Gson().fromJson(rdapResponse, JsonElement.class); + System.out.println(formatJson(rdapJson, "")); + } + + /** + * Recursively formats a JSON object into indented key-value pairs. + */ + private String formatJson(JsonElement jsonElement, String indent) { + StringBuilder sb = new StringBuilder(); + if (jsonElement.isJsonObject()) { + for (Map.Entry entry : jsonElement.getAsJsonObject().entrySet()) { + sb.append(indent).append(entry.getKey()).append(":\n"); + sb.append(formatJson(entry.getValue(), indent + " ")); + } + } else if (jsonElement.isJsonArray()) { + for (JsonElement element : jsonElement.getAsJsonArray()) { + sb.append(formatJson(element, indent + "- ")); + } + } else if (jsonElement.isJsonPrimitive()) { + sb.append(indent).append(jsonElement.getAsString()).append("\n"); + } + return sb.toString(); + } +}