mirror of
https://github.com/google/nomulus.git
synced 2025-07-08 20:23:24 +02:00
Allow the nomulus renew_domain
command to specify the client ID (#567)
* Allow the `nomulus renew_domain` command to specify the client ID This means that a superuser can renew a domain and have the associated history entry, one time billing event, and renewal grace period be recorded against a specified registrar rather than the owning registrar of the domain. This is useful to e.g. renew a domain for free by "charging" the renewal to the registry's fake registrar. Since the grace period is written to the specified cliend id as well, if the actual registrar deletes the domain, they don't get back the money that they didn't pay in the first place.
This commit is contained in:
parent
210de9340e
commit
cd13f6c5d3
3 changed files with 95 additions and 27 deletions
|
@ -153,6 +153,8 @@ public class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, D
|
|||
doSuccessfulTest(
|
||||
responseFilename,
|
||||
renewalYears,
|
||||
"TheRegistrar",
|
||||
UserPrivileges.NORMAL,
|
||||
substitutions,
|
||||
Money.of(USD, 11).multipliedBy(renewalYears));
|
||||
}
|
||||
|
@ -160,13 +162,16 @@ public class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, D
|
|||
private void doSuccessfulTest(
|
||||
String responseFilename,
|
||||
int renewalYears,
|
||||
String renewalClientId,
|
||||
UserPrivileges userPrivileges,
|
||||
Map<String, String> substitutions,
|
||||
Money totalRenewCost)
|
||||
throws Exception {
|
||||
assertTransactionalFlow(true);
|
||||
DateTime currentExpiration = reloadResourceByForeignKey().getRegistrationExpirationTime();
|
||||
DateTime newExpiration = currentExpiration.plusYears(renewalYears);
|
||||
runFlowAssertResponse(loadFile(responseFilename, substitutions));
|
||||
runFlowAssertResponse(
|
||||
CommitMode.LIVE, userPrivileges, loadFile(responseFilename, substitutions));
|
||||
DomainBase domain = reloadResourceByForeignKey();
|
||||
HistoryEntry historyEntryDomainRenew =
|
||||
getOnlyHistoryEntryOfType(domain, HistoryEntry.Type.DOMAIN_RENEW);
|
||||
|
@ -183,13 +188,13 @@ public class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, D
|
|||
.and()
|
||||
.hasLastEppUpdateTime(clock.nowUtc())
|
||||
.and()
|
||||
.hasLastEppUpdateClientId("TheRegistrar");
|
||||
.hasLastEppUpdateClientId(renewalClientId);
|
||||
assertAboutHistoryEntries().that(historyEntryDomainRenew).hasPeriodYears(renewalYears);
|
||||
BillingEvent.OneTime renewBillingEvent =
|
||||
new BillingEvent.OneTime.Builder()
|
||||
.setReason(Reason.RENEW)
|
||||
.setTargetId(getUniqueIdFromCommand())
|
||||
.setClientId("TheRegistrar")
|
||||
.setClientId(renewalClientId)
|
||||
.setCost(totalRenewCost)
|
||||
.setPeriodYears(renewalYears)
|
||||
.setEventTime(clock.nowUtc())
|
||||
|
@ -233,7 +238,7 @@ public class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, D
|
|||
GracePeriod.create(
|
||||
GracePeriodStatus.RENEW,
|
||||
clock.nowUtc().plus(Registry.get("tld").getRenewGracePeriodLength()),
|
||||
"TheRegistrar",
|
||||
renewalClientId,
|
||||
null),
|
||||
renewBillingEvent));
|
||||
}
|
||||
|
@ -256,6 +261,19 @@ public class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, D
|
|||
ImmutableMap.of("DOMAIN", "example.tld", "EXDATE", "2005-04-03T22:00:00.0Z"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_recurringClientIdIsSame_whenSuperuserOverridesRenewal() throws Exception {
|
||||
persistDomain();
|
||||
setClientIdForFlow("NewRegistrar");
|
||||
doSuccessfulTest(
|
||||
"domain_renew_response.xml",
|
||||
5,
|
||||
"NewRegistrar",
|
||||
UserPrivileges.SUPERUSER,
|
||||
ImmutableMap.of("DOMAIN", "example.tld", "EXDATE", "2005-04-03T22:00:00.0Z"),
|
||||
Money.of(USD, 55));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_customLogicFee() throws Exception {
|
||||
// The "costly-renew" domain has an additional RENEW fee of 100 from custom logic on top of the
|
||||
|
@ -269,7 +287,13 @@ public class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, D
|
|||
"FEE", "111.00");
|
||||
setEppInput("domain_renew_fee.xml", customFeeMap);
|
||||
persistDomain();
|
||||
doSuccessfulTest("domain_renew_response_fee.xml", 1, customFeeMap, Money.of(USD, 111));
|
||||
doSuccessfulTest(
|
||||
"domain_renew_response_fee.xml",
|
||||
1,
|
||||
"TheRegistrar",
|
||||
UserPrivileges.NORMAL,
|
||||
customFeeMap,
|
||||
Money.of(USD, 111));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -687,7 +711,7 @@ public class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, D
|
|||
|
||||
@Test
|
||||
public void testFailure_unauthorizedClient() throws Exception {
|
||||
sessionMetadata.setClientId("NewRegistrar");
|
||||
setClientIdForFlow("NewRegistrar");
|
||||
persistActiveDomain(getUniqueIdFromCommand());
|
||||
EppException thrown = assertThrows(ResourceNotOwnedException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
|
@ -695,7 +719,7 @@ public class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, D
|
|||
|
||||
@Test
|
||||
public void testSuccess_superuserUnauthorizedClient() throws Exception {
|
||||
sessionMetadata.setClientId("NewRegistrar");
|
||||
setClientIdForFlow("NewRegistrar");
|
||||
persistDomain();
|
||||
runFlowAssertResponse(
|
||||
CommitMode.LIVE,
|
||||
|
|
|
@ -15,21 +15,27 @@
|
|||
package google.registry.tools;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.testing.DatastoreHelper.newDomainBase;
|
||||
import static google.registry.testing.DatastoreHelper.persistActiveDomain;
|
||||
import static google.registry.testing.DatastoreHelper.persistDeletedDomain;
|
||||
import static google.registry.testing.DatastoreHelper.persistNewRegistrar;
|
||||
import static google.registry.testing.DatastoreHelper.persistResource;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
|
||||
import com.beust.jcommander.ParameterException;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import google.registry.model.domain.DomainBase;
|
||||
import google.registry.model.ofy.Ofy;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.testing.FakeClock;
|
||||
import google.registry.testing.InjectRule;
|
||||
import google.registry.util.Clock;
|
||||
import java.util.List;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.testcontainers.shaded.com.google.common.collect.ImmutableList;
|
||||
|
||||
/** Unit tests for {@link RenewDomainCommand}. */
|
||||
public class RenewDomainCommandTest extends EppToolCommandTestCase<RenewDomainCommand> {
|
||||
|
@ -63,23 +69,57 @@ public class RenewDomainCommandTest extends EppToolCommandTestCase<RenewDomainCo
|
|||
.verifyNoMoreSent();
|
||||
}
|
||||
|
||||
private static List<DomainBase> persistThreeDomains() {
|
||||
ImmutableList.Builder<DomainBase> domains = new ImmutableList.Builder<>();
|
||||
domains.add(
|
||||
persistActiveDomain(
|
||||
"domain1.tld",
|
||||
DateTime.parse("2014-09-05T05:05:05Z"),
|
||||
DateTime.parse("2015-09-05T05:05:05Z")));
|
||||
domains.add(
|
||||
persistActiveDomain(
|
||||
"domain2.tld",
|
||||
DateTime.parse("2014-11-05T05:05:05Z"),
|
||||
DateTime.parse("2015-11-05T05:05:05Z")));
|
||||
// The third domain is owned by a different registrar.
|
||||
domains.add(
|
||||
persistResource(
|
||||
newDomainBase("domain3.tld")
|
||||
.asBuilder()
|
||||
.setCreationTimeForTest(DateTime.parse("2015-01-05T05:05:05Z"))
|
||||
.setRegistrationExpirationTime(DateTime.parse("2016-01-05T05:05:05Z"))
|
||||
.setPersistedCurrentSponsorClientId("NewRegistrar")
|
||||
.build()));
|
||||
return domains.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_multipleDomains() throws Exception {
|
||||
persistActiveDomain(
|
||||
"domain1.tld",
|
||||
DateTime.parse("2014-09-05T05:05:05Z"),
|
||||
DateTime.parse("2015-09-05T05:05:05Z"));
|
||||
persistActiveDomain(
|
||||
"domain2.tld",
|
||||
DateTime.parse("2014-11-05T05:05:05Z"),
|
||||
DateTime.parse("2015-11-05T05:05:05Z"));
|
||||
persistActiveDomain(
|
||||
"domain3.tld",
|
||||
DateTime.parse("2015-01-05T05:05:05Z"),
|
||||
DateTime.parse("2016-01-05T05:05:05Z"));
|
||||
public void testSuccess_multipleDomains_renewsAndUsesEachDomainsRegistrar() throws Exception {
|
||||
persistThreeDomains();
|
||||
runCommandForced("--period 3", "domain1.tld", "domain2.tld", "domain3.tld");
|
||||
eppVerifier
|
||||
.expectClientId("TheRegistrar")
|
||||
.verifySent(
|
||||
"domain_renew.xml",
|
||||
ImmutableMap.of("DOMAIN", "domain1.tld", "EXPDATE", "2015-09-05", "YEARS", "3"))
|
||||
.verifySent(
|
||||
"domain_renew.xml",
|
||||
ImmutableMap.of("DOMAIN", "domain2.tld", "EXPDATE", "2015-11-05", "YEARS", "3"))
|
||||
.expectClientId("NewRegistrar")
|
||||
.verifySent(
|
||||
"domain_renew.xml",
|
||||
ImmutableMap.of("DOMAIN", "domain3.tld", "EXPDATE", "2016-01-05", "YEARS", "3"))
|
||||
.verifyNoMoreSent();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_multipleDomains_renewsAndUsesSpecifiedRegistrar() throws Exception {
|
||||
persistThreeDomains();
|
||||
persistNewRegistrar("reg3", "Registrar 3", Registrar.Type.REAL, 9783L);
|
||||
runCommandForced("--period 3", "domain1.tld", "domain2.tld", "domain3.tld", "-u", "-c reg3");
|
||||
eppVerifier
|
||||
.expectClientId("reg3")
|
||||
.expectSuperuser()
|
||||
.verifySent(
|
||||
"domain_renew.xml",
|
||||
ImmutableMap.of("DOMAIN", "domain1.tld", "EXPDATE", "2015-09-05", "YEARS", "3"))
|
||||
|
@ -106,9 +146,7 @@ public class RenewDomainCommandTest extends EppToolCommandTestCase<RenewDomainCo
|
|||
persistDeletedDomain("deleted.tld", DateTime.parse("2012-10-05T05:05:05Z"));
|
||||
IllegalArgumentException e =
|
||||
assertThrows(IllegalArgumentException.class, () -> runCommandForced("deleted.tld"));
|
||||
assertThat(e)
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Domain 'deleted.tld' does not exist or is deleted");
|
||||
assertThat(e).hasMessageThat().isEqualTo("Domain 'deleted.tld' does not exist or is deleted");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -128,9 +166,7 @@ public class RenewDomainCommandTest extends EppToolCommandTestCase<RenewDomainCo
|
|||
IllegalArgumentException e =
|
||||
assertThrows(
|
||||
IllegalArgumentException.class, () -> runCommandForced("domain.tld", "--period 10"));
|
||||
assertThat(e)
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Cannot renew domains for 10 or more years");
|
||||
assertThat(e).hasMessageThat().isEqualTo("Cannot renew domains for 10 or more years");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue