diff --git a/java/google/registry/flows/domain/ClaimsCheckFlow.java b/java/google/registry/flows/domain/ClaimsCheckFlow.java index a80682d83..b8117297f 100644 --- a/java/google/registry/flows/domain/ClaimsCheckFlow.java +++ b/java/google/registry/flows/domain/ClaimsCheckFlow.java @@ -89,9 +89,9 @@ public final class ClaimsCheckFlow implements Flow { String tld = domainName.parent().toString(); // Only validate access to a TLD the first time it is encountered. if (seenTlds.add(tld)) { - checkAllowedAccessToTld(clientId, tld); - Registry registry = Registry.get(tld); if (!isSuperuser) { + checkAllowedAccessToTld(clientId, tld); + Registry registry = Registry.get(tld); DateTime now = clock.nowUtc(); verifyNotInPredelegation(registry, now); if (registry.getTldState(now) == TldState.SUNRISE) { diff --git a/java/google/registry/flows/domain/DomainApplicationCreateFlow.java b/java/google/registry/flows/domain/DomainApplicationCreateFlow.java index 20d7e24ed..8b7b37c5c 100644 --- a/java/google/registry/flows/domain/DomainApplicationCreateFlow.java +++ b/java/google/registry/flows/domain/DomainApplicationCreateFlow.java @@ -203,7 +203,10 @@ public final class DomainApplicationCreateFlow implements TransactionalFlow { InternetDomainName domainName = validateDomainName(targetId); String idnTableName = validateDomainNameWithIdnTables(domainName); String tld = domainName.parent().toString(); - checkAllowedAccessToTld(clientId, tld); + if (!isSuperuser) { + // Access to the TLD should be checked before the subsequent checks as it is a greater concern + checkAllowedAccessToTld(clientId, tld); + } Registry registry = Registry.get(tld); FeesAndCredits feesAndCredits = pricingLogic.getCreatePrice(registry, targetId, now, command.getPeriod().getValue()); diff --git a/java/google/registry/flows/domain/DomainApplicationDeleteFlow.java b/java/google/registry/flows/domain/DomainApplicationDeleteFlow.java index 05b379527..af061c0dd 100644 --- a/java/google/registry/flows/domain/DomainApplicationDeleteFlow.java +++ b/java/google/registry/flows/domain/DomainApplicationDeleteFlow.java @@ -88,8 +88,8 @@ public final class DomainApplicationDeleteFlow implements TransactionalFlow { verifyApplicationDomainMatchesTargetId(existingApplication, targetId); verifyOptionalAuthInfo(authInfo, existingApplication); String tld = existingApplication.getTld(); - checkAllowedAccessToTld(clientId, tld); if (!isSuperuser) { + checkAllowedAccessToTld(clientId, tld); Registry registry = Registry.get(tld); verifyRegistryStateAllowsLaunchFlows(registry, now); verifyLaunchPhaseMatchesRegistryPhase( diff --git a/java/google/registry/flows/domain/DomainApplicationUpdateFlow.java b/java/google/registry/flows/domain/DomainApplicationUpdateFlow.java index b2c0e67f6..feb83b0ba 100644 --- a/java/google/registry/flows/domain/DomainApplicationUpdateFlow.java +++ b/java/google/registry/flows/domain/DomainApplicationUpdateFlow.java @@ -174,13 +174,13 @@ public class DomainApplicationUpdateFlow implements TransactionalFlow { DomainApplication existingApplication, Update command, DateTime now) throws EppException { AddRemove add = command.getInnerAdd(); AddRemove remove = command.getInnerRemove(); + String tld = existingApplication.getTld(); if (!isSuperuser) { verifyResourceOwnership(clientId, existingApplication); verifyClientUpdateNotProhibited(command, existingApplication); verifyAllStatusesAreClientSettable(union(add.getStatusValues(), remove.getStatusValues())); + checkAllowedAccessToTld(clientId, tld); } - String tld = existingApplication.getTld(); - checkAllowedAccessToTld(clientId, tld); if (UPDATE_DISALLOWED_APPLICATION_STATUSES .contains(existingApplication.getApplicationStatus())) { throw new ApplicationStatusProhibitsUpdateException( diff --git a/java/google/registry/flows/domain/DomainCheckFlow.java b/java/google/registry/flows/domain/DomainCheckFlow.java index efad7081a..35cc5595f 100644 --- a/java/google/registry/flows/domain/DomainCheckFlow.java +++ b/java/google/registry/flows/domain/DomainCheckFlow.java @@ -136,11 +136,10 @@ public final class DomainCheckFlow implements Flow { // This validation is moderately expensive, so cache the results. domains.put(targetId, domainName); String tld = domainName.parent().toString(); - if (seenTlds.add(tld)) { + boolean tldFirstTimeSeen = seenTlds.add(tld); + if (tldFirstTimeSeen && !isSuperuser) { checkAllowedAccessToTld(clientId, tld); - if (!isSuperuser) { - verifyNotInPredelegation(Registry.get(tld), now); - } + verifyNotInPredelegation(Registry.get(tld), now); } } ImmutableMap domainNames = domains.build(); diff --git a/java/google/registry/flows/domain/DomainDeleteFlow.java b/java/google/registry/flows/domain/DomainDeleteFlow.java index ad95c988d..a0c55e226 100644 --- a/java/google/registry/flows/domain/DomainDeleteFlow.java +++ b/java/google/registry/flows/domain/DomainDeleteFlow.java @@ -211,8 +211,8 @@ public final class DomainDeleteFlow implements TransactionalFlow { if (!isSuperuser) { verifyResourceOwnership(clientId, existingDomain); verifyNotInPredelegation(registry, now); + checkAllowedAccessToTld(clientId, registry.getTld().toString()); } - checkAllowedAccessToTld(clientId, registry.getTld().toString()); if (!existingDomain.getSubordinateHosts().isEmpty()) { throw new DomainToDeleteHasHostsException(); } diff --git a/java/google/registry/flows/domain/DomainRenewFlow.java b/java/google/registry/flows/domain/DomainRenewFlow.java index b6033ade2..2f753c87a 100644 --- a/java/google/registry/flows/domain/DomainRenewFlow.java +++ b/java/google/registry/flows/domain/DomainRenewFlow.java @@ -219,8 +219,8 @@ public final class DomainRenewFlow implements TransactionalFlow { verifyNoDisallowedStatuses(existingDomain, RENEW_DISALLOWED_STATUSES); if (!isSuperuser) { verifyResourceOwnership(clientId, existingDomain); + checkAllowedAccessToTld(clientId, existingDomain.getTld()); } - checkAllowedAccessToTld(clientId, existingDomain.getTld()); verifyUnitIsYears(command.getPeriod()); // If the date they specify doesn't match the expiration, fail. (This is an idempotence check). if (!command.getCurrentExpirationDate().equals( diff --git a/java/google/registry/flows/domain/DomainRestoreRequestFlow.java b/java/google/registry/flows/domain/DomainRestoreRequestFlow.java index ec6ea350c..54e61ee67 100644 --- a/java/google/registry/flows/domain/DomainRestoreRequestFlow.java +++ b/java/google/registry/flows/domain/DomainRestoreRequestFlow.java @@ -188,6 +188,7 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow { verifyResourceOwnership(clientId, existingDomain); verifyNotReserved(InternetDomainName.from(targetId), false); verifyPremiumNameIsNotBlocked(targetId, now, clientId); + checkAllowedAccessToTld(clientId, existingDomain.getTld()); } // No other changes can be specified on a restore request. if (!command.noChangesPresent()) { @@ -197,7 +198,6 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow { if (!existingDomain.getGracePeriodStatuses().contains(GracePeriodStatus.REDEMPTION)) { throw new DomainNotEligibleForRestoreException(); } - checkAllowedAccessToTld(clientId, existingDomain.getTld()); validateFeeChallenge(targetId, existingDomain.getTld(), now, feeUpdate, feesAndCredits); } diff --git a/java/google/registry/flows/domain/DomainTransferApproveFlow.java b/java/google/registry/flows/domain/DomainTransferApproveFlow.java index ddd210e3a..8b2295d34 100644 --- a/java/google/registry/flows/domain/DomainTransferApproveFlow.java +++ b/java/google/registry/flows/domain/DomainTransferApproveFlow.java @@ -36,6 +36,7 @@ import com.googlecode.objectify.Key; import google.registry.flows.EppException; import google.registry.flows.ExtensionManager; import google.registry.flows.FlowModule.ClientId; +import google.registry.flows.FlowModule.Superuser; import google.registry.flows.FlowModule.TargetId; import google.registry.flows.TransactionalFlow; import google.registry.flows.annotations.ReportingSpec; @@ -83,6 +84,7 @@ public final class DomainTransferApproveFlow implements TransactionalFlow { @Inject Optional authInfo; @Inject @ClientId String clientId; @Inject @TargetId String targetId; + @Inject @Superuser boolean isSuperuser; @Inject HistoryEntry.Builder historyBuilder; @Inject EppResponse.Builder responseBuilder; @Inject DomainTransferApproveFlow() {} @@ -102,7 +104,9 @@ public final class DomainTransferApproveFlow implements TransactionalFlow { verifyHasPendingTransfer(existingDomain); verifyResourceOwnership(clientId, existingDomain); String tld = existingDomain.getTld(); - checkAllowedAccessToTld(clientId, tld); + if (!isSuperuser) { + checkAllowedAccessToTld(clientId, tld); + } TransferData transferData = existingDomain.getTransferData(); String gainingClientId = transferData.getGainingClientId(); HistoryEntry historyEntry = historyBuilder diff --git a/java/google/registry/flows/domain/DomainTransferCancelFlow.java b/java/google/registry/flows/domain/DomainTransferCancelFlow.java index 6a0874faf..337ca68fc 100644 --- a/java/google/registry/flows/domain/DomainTransferCancelFlow.java +++ b/java/google/registry/flows/domain/DomainTransferCancelFlow.java @@ -32,6 +32,7 @@ import com.googlecode.objectify.Key; import google.registry.flows.EppException; import google.registry.flows.ExtensionManager; import google.registry.flows.FlowModule.ClientId; +import google.registry.flows.FlowModule.Superuser; import google.registry.flows.FlowModule.TargetId; import google.registry.flows.TransactionalFlow; import google.registry.flows.annotations.ReportingSpec; @@ -71,6 +72,7 @@ public final class DomainTransferCancelFlow implements TransactionalFlow { @Inject Optional authInfo; @Inject @ClientId String clientId; @Inject @TargetId String targetId; + @Inject @Superuser boolean isSuperuser; @Inject HistoryEntry.Builder historyBuilder; @Inject EppResponse.Builder responseBuilder; @Inject DomainTransferCancelFlow() {} @@ -85,7 +87,9 @@ public final class DomainTransferCancelFlow implements TransactionalFlow { verifyOptionalAuthInfo(authInfo, existingDomain); verifyHasPendingTransfer(existingDomain); verifyTransferInitiator(clientId, existingDomain); - checkAllowedAccessToTld(clientId, existingDomain.getTld()); + if (!isSuperuser) { + checkAllowedAccessToTld(clientId, existingDomain.getTld()); + } HistoryEntry historyEntry = historyBuilder .setType(HistoryEntry.Type.DOMAIN_TRANSFER_CANCEL) .setOtherClientId(existingDomain.getTransferData().getLosingClientId()) diff --git a/java/google/registry/flows/domain/DomainTransferRejectFlow.java b/java/google/registry/flows/domain/DomainTransferRejectFlow.java index f776b7dd0..589d0398a 100644 --- a/java/google/registry/flows/domain/DomainTransferRejectFlow.java +++ b/java/google/registry/flows/domain/DomainTransferRejectFlow.java @@ -32,6 +32,7 @@ import com.googlecode.objectify.Key; import google.registry.flows.EppException; import google.registry.flows.ExtensionManager; import google.registry.flows.FlowModule.ClientId; +import google.registry.flows.FlowModule.Superuser; import google.registry.flows.FlowModule.TargetId; import google.registry.flows.TransactionalFlow; import google.registry.flows.annotations.ReportingSpec; @@ -71,6 +72,7 @@ public final class DomainTransferRejectFlow implements TransactionalFlow { @Inject Optional authInfo; @Inject @ClientId String clientId; @Inject @TargetId String targetId; + @Inject @Superuser boolean isSuperuser; @Inject HistoryEntry.Builder historyBuilder; @Inject EppResponse.Builder responseBuilder; @Inject DomainTransferRejectFlow() {} @@ -91,7 +93,9 @@ public final class DomainTransferRejectFlow implements TransactionalFlow { verifyOptionalAuthInfo(authInfo, existingDomain); verifyHasPendingTransfer(existingDomain); verifyResourceOwnership(clientId, existingDomain); - checkAllowedAccessToTld(clientId, existingDomain.getTld()); + if (!isSuperuser) { + checkAllowedAccessToTld(clientId, existingDomain.getTld()); + } DomainResource newDomain = denyPendingTransfer(existingDomain, TransferStatus.CLIENT_REJECTED, now); ofy().save().entities( diff --git a/java/google/registry/flows/domain/DomainTransferRequestFlow.java b/java/google/registry/flows/domain/DomainTransferRequestFlow.java index 0e9e78df3..41351078a 100644 --- a/java/google/registry/flows/domain/DomainTransferRequestFlow.java +++ b/java/google/registry/flows/domain/DomainTransferRequestFlow.java @@ -217,9 +217,9 @@ public final class DomainTransferRequestFlow implements TransactionalFlow { if (gainingClientId.equals(existingDomain.getCurrentSponsorClientId())) { throw new ObjectAlreadySponsoredException(); } - checkAllowedAccessToTld(gainingClientId, existingDomain.getTld()); verifyTransferPeriodIsOneYear(period); if (!isSuperuser) { + checkAllowedAccessToTld(gainingClientId, existingDomain.getTld()); verifyPremiumNameIsNotBlocked(targetId, now, gainingClientId); } } diff --git a/java/google/registry/flows/domain/DomainUpdateFlow.java b/java/google/registry/flows/domain/DomainUpdateFlow.java index 1a27b5235..180bf686a 100644 --- a/java/google/registry/flows/domain/DomainUpdateFlow.java +++ b/java/google/registry/flows/domain/DomainUpdateFlow.java @@ -212,14 +212,14 @@ public final class DomainUpdateFlow implements TransactionalFlow { verifyOptionalAuthInfo(authInfo, existingDomain); AddRemove add = command.getInnerAdd(); AddRemove remove = command.getInnerRemove(); + String tld = existingDomain.getTld(); if (!isSuperuser) { verifyResourceOwnership(clientId, existingDomain); verifyClientUpdateNotProhibited(command, existingDomain); verifyAllStatusesAreClientSettable(union(add.getStatusValues(), remove.getStatusValues())); + checkAllowedAccessToTld(clientId, tld); } - String tld = existingDomain.getTld(); Registry registry = Registry.get(tld); - checkAllowedAccessToTld(clientId, tld); FeeTransformCommandExtension feeUpdate = eppInput.getSingleExtension(FeeUpdateCommandExtension.class); // If the fee extension is present, validate it (even if the cost is zero, to check for price diff --git a/javatests/google/registry/flows/domain/ClaimsCheckFlowTest.java b/javatests/google/registry/flows/domain/ClaimsCheckFlowTest.java index 40550782e..b82aa8ac5 100644 --- a/javatests/google/registry/flows/domain/ClaimsCheckFlowTest.java +++ b/javatests/google/registry/flows/domain/ClaimsCheckFlowTest.java @@ -31,7 +31,6 @@ import google.registry.model.domain.DomainResource; import google.registry.model.registrar.Registrar; import google.registry.model.registry.Registry; import google.registry.model.registry.Registry.TldState; -import google.registry.testing.DatastoreHelper; import org.junit.Before; import org.junit.Test; @@ -81,7 +80,6 @@ public class ClaimsCheckFlowTest extends ResourceFlowTestCaseof()) @@ -124,6 +122,22 @@ public class ClaimsCheckFlowTest extends ResourceFlowTestCaseof()) + .build()); + assertTransactionalFlow(false); + assertNoHistory(); // Checks don't create a history event. + assertNoBillingEvents(); // Checks are always free. + runFlowAssertResponse( + CommitMode.LIVE, UserPrivileges.SUPERUSER, readFile("domain_check_claims_response.xml")); + } + @Test public void testFailure_predelgation() throws Exception { createTld("tld", TldState.PREDELEGATION); diff --git a/javatests/google/registry/flows/domain/DomainApplicationCreateFlowTest.java b/javatests/google/registry/flows/domain/DomainApplicationCreateFlowTest.java index 023813947..c42a3de09 100644 --- a/javatests/google/registry/flows/domain/DomainApplicationCreateFlowTest.java +++ b/javatests/google/registry/flows/domain/DomainApplicationCreateFlowTest.java @@ -1131,6 +1131,17 @@ public class DomainApplicationCreateFlowTest runSuperuserFlow("domain_create_sunrush_response.xml"); } + @Test + public void testSuccess_superuserNotAuthorizedForTld() throws Exception { + DatastoreHelper.persistResource(Registrar.loadByClientId("TheRegistrar") + .asBuilder() + .setAllowedTlds(ImmutableSet.of()) + .build()); + persistContactsAndHosts(); + clock.advanceOneMilli(); + runSuperuserFlow("domain_create_sunrise_encoded_signed_mark_response.xml"); + } + @Test public void testSuccess_superuserSunrush() throws Exception { createTld("tld", TldState.SUNRUSH); diff --git a/javatests/google/registry/flows/domain/DomainApplicationDeleteFlowTest.java b/javatests/google/registry/flows/domain/DomainApplicationDeleteFlowTest.java index dac8c5b0f..77ecb33c2 100644 --- a/javatests/google/registry/flows/domain/DomainApplicationDeleteFlowTest.java +++ b/javatests/google/registry/flows/domain/DomainApplicationDeleteFlowTest.java @@ -150,6 +150,16 @@ public class DomainApplicationDeleteFlowTest runFlow(); } + @Test + public void testSuccess_superuserUnauthorizedClient() throws Exception { + sessionMetadata.setClientId("NewRegistrar"); + persistResource( + newDomainApplication("example.tld").asBuilder().setRepoId("1-TLD").build()); + clock.advanceOneMilli(); + runFlowAssertResponse( + CommitMode.LIVE, UserPrivileges.SUPERUSER, readFile("domain_delete_response.xml")); + } + @Test public void testFailure_notAuthorizedForTld() throws Exception { persistResource( @@ -162,12 +172,16 @@ public class DomainApplicationDeleteFlowTest thrown.expect(NotAuthorizedForTldException.class); runFlow(); } - + @Test - public void testSuccess_superuserUnauthorizedClient() throws Exception { - sessionMetadata.setClientId("NewRegistrar"); + public void testSuccess_superuserNotAuthorizedForTld() throws Exception { persistResource( newDomainApplication("example.tld").asBuilder().setRepoId("1-TLD").build()); + persistResource( + Registrar.loadByClientId("TheRegistrar") + .asBuilder() + .setAllowedTlds(ImmutableSet.of()) + .build()); clock.advanceOneMilli(); runFlowAssertResponse( CommitMode.LIVE, UserPrivileges.SUPERUSER, readFile("domain_delete_response.xml")); diff --git a/javatests/google/registry/flows/domain/DomainApplicationUpdateFlowTest.java b/javatests/google/registry/flows/domain/DomainApplicationUpdateFlowTest.java index abba30850..cf7539405 100644 --- a/javatests/google/registry/flows/domain/DomainApplicationUpdateFlowTest.java +++ b/javatests/google/registry/flows/domain/DomainApplicationUpdateFlowTest.java @@ -562,6 +562,16 @@ public class DomainApplicationUpdateFlowTest runFlow(); } + @Test + public void testSuccess_superuserUnauthorizedClient() throws Exception { + sessionMetadata.setClientId("NewRegistrar"); + persistReferencedEntities(); + persistApplication(); + clock.advanceOneMilli(); + runFlowAssertResponse( + CommitMode.LIVE, UserPrivileges.SUPERUSER, readFile("domain_update_response.xml")); + } + @Test public void testFailure_notAuthorizedForTld() throws Exception { persistResource( @@ -574,10 +584,14 @@ public class DomainApplicationUpdateFlowTest thrown.expect(NotAuthorizedForTldException.class); runFlow(); } - + @Test - public void testSuccess_superuserUnauthorizedClient() throws Exception { - sessionMetadata.setClientId("NewRegistrar"); + public void testSuccess_superuserNotAuthorizedForTld() throws Exception { + persistResource( + Registrar.loadByClientId("TheRegistrar") + .asBuilder() + .setAllowedTlds(ImmutableSet.of()) + .build()); persistReferencedEntities(); persistApplication(); clock.advanceOneMilli(); diff --git a/javatests/google/registry/flows/domain/DomainCheckFlowTest.java b/javatests/google/registry/flows/domain/DomainCheckFlowTest.java index 77d13a044..e2079dccb 100644 --- a/javatests/google/registry/flows/domain/DomainCheckFlowTest.java +++ b/javatests/google/registry/flows/domain/DomainCheckFlowTest.java @@ -294,6 +294,18 @@ public class DomainCheckFlowTest runFlow(); } + @Test + public void testSuccess_superuserNotAuthorizedForTld() throws Exception { + persistActiveDomain("example2.tld"); + DatastoreHelper.persistResource( + Registrar.loadByClientId("TheRegistrar") + .asBuilder() + .setAllowedTlds(ImmutableSet.of()) + .build()); + runFlowAssertResponse( + CommitMode.LIVE, UserPrivileges.SUPERUSER, readFile("domain_check_one_tld_response.xml")); + } + private void doFailingBadLabelTest(String label, Class expectedException) throws Exception { setEppInput("domain_check_template.xml", ImmutableMap.of("LABEL", label)); diff --git a/javatests/google/registry/flows/domain/DomainDeleteFlowTest.java b/javatests/google/registry/flows/domain/DomainDeleteFlowTest.java index ccbaf134d..469c4ef1f 100644 --- a/javatests/google/registry/flows/domain/DomainDeleteFlowTest.java +++ b/javatests/google/registry/flows/domain/DomainDeleteFlowTest.java @@ -678,6 +678,15 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCaseof()) + .build()); clock.advanceOneMilli(); runFlowAssertResponse( CommitMode.LIVE, UserPrivileges.SUPERUSER, readFile("domain_delete_response_pending.xml")); diff --git a/javatests/google/registry/flows/domain/DomainRenewFlowTest.java b/javatests/google/registry/flows/domain/DomainRenewFlowTest.java index 4d9ca17d7..89130fdb0 100644 --- a/javatests/google/registry/flows/domain/DomainRenewFlowTest.java +++ b/javatests/google/registry/flows/domain/DomainRenewFlowTest.java @@ -611,6 +611,14 @@ public class DomainRenewFlowTest extends ResourceFlowTestCaseof()) + .build()); persistDomain(); runFlowAssertResponse( CommitMode.LIVE, UserPrivileges.SUPERUSER, readFile("domain_renew_response.xml")); diff --git a/javatests/google/registry/flows/domain/DomainRestoreRequestFlowTest.java b/javatests/google/registry/flows/domain/DomainRestoreRequestFlowTest.java index 83e716d37..bd0215830 100644 --- a/javatests/google/registry/flows/domain/DomainRestoreRequestFlowTest.java +++ b/javatests/google/registry/flows/domain/DomainRestoreRequestFlowTest.java @@ -494,6 +494,14 @@ public class DomainRestoreRequestFlowTest extends runFlow(); } + @Test + public void testSuccess_superuserUnauthorizedClient() throws Exception { + sessionMetadata.setClientId("NewRegistrar"); + persistPendingDeleteDomain(); + thrown.expect(ResourceNotOwnedException.class); + runFlowAssertResponse(readFile("domain_update_response.xml")); + } + @Test public void testFailure_notAuthorizedForTld() throws Exception { persistResource( @@ -507,11 +515,17 @@ public class DomainRestoreRequestFlowTest extends } @Test - public void testSuccess_superuserUnauthorizedClient() throws Exception { - sessionMetadata.setClientId("NewRegistrar"); + public void testSuccess_superuserNotAuthorizedForTld() throws Exception { + persistResource( + Registrar.loadByClientId("TheRegistrar") + .asBuilder() + .setAllowedTlds(ImmutableSet.of()) + .build()); persistPendingDeleteDomain(); - thrown.expect(ResourceNotOwnedException.class); - runFlowAssertResponse(readFile("domain_update_response.xml")); + runFlowAssertResponse( + CommitMode.LIVE, + UserPrivileges.SUPERUSER, + readFile("domain_update_response.xml")); } @Test diff --git a/javatests/google/registry/flows/domain/DomainTransferApproveFlowTest.java b/javatests/google/registry/flows/domain/DomainTransferApproveFlowTest.java index be4c80f53..b8a089d64 100644 --- a/javatests/google/registry/flows/domain/DomainTransferApproveFlowTest.java +++ b/javatests/google/registry/flows/domain/DomainTransferApproveFlowTest.java @@ -423,6 +423,19 @@ public class DomainTransferApproveFlowTest doSuccessfulTest("tld", "domain_transfer_approve.xml", "domain_transfer_approve_response.xml"); } + @Test + public void testSuccess_superuserNotAuthorizedForTld() throws Exception { + persistResource( + Registrar.loadByClientId("TheRegistrar") + .asBuilder() + .setAllowedTlds(ImmutableSet.of()) + .build()); + runFlowAssertResponse( + CommitMode.LIVE, + UserPrivileges.SUPERUSER, + readFile("domain_transfer_approve_response.xml")); + } + // NB: No need to test pending delete status since pending transfers will get cancelled upon // entering pending delete phase. So it's already handled in that test case. diff --git a/javatests/google/registry/flows/domain/DomainTransferCancelFlowTest.java b/javatests/google/registry/flows/domain/DomainTransferCancelFlowTest.java index 36d4ee4d2..64e515404 100644 --- a/javatests/google/registry/flows/domain/DomainTransferCancelFlowTest.java +++ b/javatests/google/registry/flows/domain/DomainTransferCancelFlowTest.java @@ -299,6 +299,20 @@ public class DomainTransferCancelFlowTest doSuccessfulTest("domain_transfer_cancel.xml", "domain_transfer_cancel_response.xml"); } + @Test + public void testSuccess_superuserNotAuthorizedForTld() throws Exception { + persistResource( + Registrar.loadByClientId("NewRegistrar") + .asBuilder() + .setAllowedTlds(ImmutableSet.of()) + .build()); + clock.advanceOneMilli(); + runFlowAssertResponse( + CommitMode.LIVE, + UserPrivileges.SUPERUSER, + readFile("domain_transfer_cancel_response.xml")); + } + // NB: No need to test pending delete status since pending transfers will get cancelled upon // entering pending delete phase. So it's already handled in that test case. diff --git a/javatests/google/registry/flows/domain/DomainTransferRejectFlowTest.java b/javatests/google/registry/flows/domain/DomainTransferRejectFlowTest.java index 4a843a7b6..470eaee75 100644 --- a/javatests/google/registry/flows/domain/DomainTransferRejectFlowTest.java +++ b/javatests/google/registry/flows/domain/DomainTransferRejectFlowTest.java @@ -166,6 +166,19 @@ public class DomainTransferRejectFlowTest doSuccessfulTest("domain_transfer_reject.xml", "domain_transfer_reject_response.xml"); } + @Test + public void testSuccess_superuserNotAuthorizedForTld() throws Exception { + persistResource( + Registrar.loadByClientId("TheRegistrar") + .asBuilder() + .setAllowedTlds(ImmutableSet.of()) + .build()); + runFlowAssertResponse( + CommitMode.LIVE, + UserPrivileges.SUPERUSER, + readFile("domain_transfer_reject_response.xml")); + } + @Test public void testFailure_badContactPassword() throws Exception { // Change the contact's password so it does not match the password in the file. diff --git a/javatests/google/registry/flows/domain/DomainTransferRequestFlowTest.java b/javatests/google/registry/flows/domain/DomainTransferRequestFlowTest.java index 7c3e18176..ac89b65f8 100644 --- a/javatests/google/registry/flows/domain/DomainTransferRequestFlowTest.java +++ b/javatests/google/registry/flows/domain/DomainTransferRequestFlowTest.java @@ -571,6 +571,19 @@ public class DomainTransferRequestFlowTest doSuccessfulTest("domain_transfer_request.xml", "domain_transfer_request_response.xml"); } + @Test + public void testSuccess_superuserNotAuthorizedForTld() throws Exception { + setupDomain("example", "tld"); + persistResource( + Registrar.loadByClientId("NewRegistrar") + .asBuilder() + .setAllowedTlds(ImmutableSet.of()) + .build()); + clock.advanceOneMilli(); + // We don't verify the results; just check that the flow doesn't fail. + runTest("domain_transfer_request.xml", UserPrivileges.SUPERUSER); + } + @Test public void testSuccess_autorenewGraceActive_onlyAtTransferRequestTime() throws Exception { setupDomain("example", "tld"); diff --git a/javatests/google/registry/flows/domain/DomainUpdateFlowTest.java b/javatests/google/registry/flows/domain/DomainUpdateFlowTest.java index be24be11c..c7d1a5da9 100644 --- a/javatests/google/registry/flows/domain/DomainUpdateFlowTest.java +++ b/javatests/google/registry/flows/domain/DomainUpdateFlowTest.java @@ -961,6 +961,16 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCaseof()) + .build()); persistReferencedEntities(); persistDomain(); clock.advanceOneMilli();