mirror of
https://github.com/google/nomulus
synced 2026-07-06 00:04:50 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7b34659a8f | |||
| 808432e709 |
@@ -14,7 +14,6 @@
|
||||
|
||||
package google.registry.model.console;
|
||||
|
||||
|
||||
import google.registry.persistence.VKey;
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.AccessType;
|
||||
@@ -58,6 +57,5 @@ public class User extends UserBase {
|
||||
public Builder(User user) {
|
||||
super(user);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
import google.registry.model.Buildable;
|
||||
import google.registry.model.UpdateAutoTimestampEntity;
|
||||
import google.registry.util.PasswordUtils;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.AccessType;
|
||||
import javax.persistence.Column;
|
||||
@@ -54,6 +56,9 @@ public class UserBase extends UpdateAutoTimestampEntity implements Buildable {
|
||||
@Column(nullable = false)
|
||||
String emailAddress;
|
||||
|
||||
/** Optional external email address to use for registry lock confirmation emails. */
|
||||
@Column String registryLockEmailAddress;
|
||||
|
||||
/** Roles (which grant permissions) associated with this user. */
|
||||
@Column(nullable = false)
|
||||
UserRoles userRoles;
|
||||
@@ -89,6 +94,10 @@ public class UserBase extends UpdateAutoTimestampEntity implements Buildable {
|
||||
return emailAddress;
|
||||
}
|
||||
|
||||
public Optional<String> getRegistryLockEmailAddress() {
|
||||
return Optional.ofNullable(registryLockEmailAddress);
|
||||
}
|
||||
|
||||
public UserRoles getUserRoles() {
|
||||
return userRoles;
|
||||
}
|
||||
@@ -150,6 +159,12 @@ public class UserBase extends UpdateAutoTimestampEntity implements Buildable {
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setRegistryLockEmailAddress(@Nullable String registryLockEmailAddress) {
|
||||
getInstance().registryLockEmailAddress =
|
||||
registryLockEmailAddress == null ? null : checkValidEmail(registryLockEmailAddress);
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setUserRoles(UserRoles userRoles) {
|
||||
checkArgumentNotNull(userRoles, "User roles cannot be null");
|
||||
getInstance().userRoles = userRoles;
|
||||
|
||||
@@ -458,20 +458,6 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
|
||||
@JsonDeserialize(using = CurrencyDeserializer.class)
|
||||
CurrencyUnit currency = DEFAULT_CURRENCY;
|
||||
|
||||
// TODO(sarahbot@): Remove this field once all saved configuration files have this field removed
|
||||
/** The per-year billing cost for registering a new domain name. */
|
||||
@Deprecated
|
||||
@JsonIgnore
|
||||
@Type(type = JodaMoneyType.TYPE_NAME)
|
||||
@Columns(
|
||||
columns = {
|
||||
@Column(name = "create_billing_cost_amount"),
|
||||
@Column(name = "create_billing_cost_currency")
|
||||
})
|
||||
Money createBillingCost = DEFAULT_CREATE_BILLING_COST;
|
||||
|
||||
// TODO(sarahbot@): Rename this field to createBillingCost once the old createBillingCost has been
|
||||
// removed
|
||||
/** A property that transitions to different create billing costs at different times. */
|
||||
@Column(nullable = false)
|
||||
@JsonDeserialize(using = TimedTransitionPropertyMoneyDeserializer.class)
|
||||
@@ -682,19 +668,10 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
|
||||
* Use {@code PricingEngineProxy.getDomainCreateCost} instead of this to find the cost for a
|
||||
* domain create.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public Money getCreateBillingCost(DateTime now) {
|
||||
return createBillingCostTransitions.getValueAtTime(now);
|
||||
}
|
||||
|
||||
// This getter is still necessary for the Jackson deserialization in the ConfigureTldCommand
|
||||
// TODO(sarahbot@): Remove this getter once the deprecated createBillingCost field is removed from
|
||||
// the schema
|
||||
@Deprecated
|
||||
public Money getCreateBillingCost() {
|
||||
return createBillingCost;
|
||||
}
|
||||
|
||||
public ImmutableSortedMap<DateTime, Money> getCreateBillingCostTransitions() {
|
||||
return createBillingCostTransitions.toValueMap();
|
||||
}
|
||||
@@ -976,12 +953,6 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setCreateBillingCost(Money amount) {
|
||||
checkArgument(amount.isPositiveOrZero(), "createBillingCost cannot be negative");
|
||||
getInstance().createBillingCost = amount;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setCreateBillingCostTransitions(
|
||||
ImmutableSortedMap<DateTime, Money> createCostsMap) {
|
||||
checkArgumentNotNull(createCostsMap, "Create billing costs map cannot be null");
|
||||
|
||||
@@ -34,6 +34,14 @@ public abstract class CreateOrUpdateUserCommand extends ConfirmingCommand {
|
||||
@Parameter(names = "--email", description = "Email address of the user", required = true)
|
||||
String email;
|
||||
|
||||
@Nullable
|
||||
@Parameter(
|
||||
names = "--registry_lock_email_address",
|
||||
description =
|
||||
"Optional external email address to use for registry lock confirmation emails, or empty"
|
||||
+ " to remove the field.")
|
||||
private String registryLockEmailAddress;
|
||||
|
||||
@Nullable
|
||||
@Parameter(
|
||||
names = "--admin",
|
||||
@@ -78,6 +86,16 @@ public abstract class CreateOrUpdateUserCommand extends ConfirmingCommand {
|
||||
User.Builder builder =
|
||||
(user == null) ? new User.Builder().setEmailAddress(email) : user.asBuilder();
|
||||
builder.setUserRoles(userRolesBuilder.build());
|
||||
|
||||
// An empty registryLockEmailAddress indicates that we should remove the field
|
||||
if (registryLockEmailAddress != null) {
|
||||
if (registryLockEmailAddress.isEmpty()) {
|
||||
builder.setRegistryLockEmailAddress(null);
|
||||
} else {
|
||||
builder.setRegistryLockEmailAddress(registryLockEmailAddress);
|
||||
}
|
||||
}
|
||||
|
||||
User newUser = builder.build();
|
||||
UserDao.saveUser(newUser);
|
||||
}
|
||||
|
||||
+10
-3
@@ -150,20 +150,27 @@ public class ConsoleRegistryLockAction extends ConsoleApiAction {
|
||||
}
|
||||
}
|
||||
|
||||
String userEmail = user.getEmailAddress();
|
||||
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, userEmail, isAdmin)
|
||||
domainName, registrarId, registryLockEmail, isAdmin)
|
||||
: domainLockUtils.saveNewRegistryUnlockRequest(
|
||||
domainName,
|
||||
registrarId,
|
||||
isAdmin,
|
||||
relockDurationMillis.map(Duration::new));
|
||||
sendVerificationEmail(registryLock, userEmail, isLock);
|
||||
sendVerificationEmail(registryLock, registryLockEmail, isLock);
|
||||
});
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Catch IllegalArgumentExceptions separately to give a nicer error message and code
|
||||
|
||||
@@ -199,7 +199,8 @@ public class RegistryLockPostAction implements Runnable, JsonActionRunner.JsonAc
|
||||
checkArgument(
|
||||
user.verifyRegistryLockPassword(postInput.password),
|
||||
"Incorrect registry lock password for user");
|
||||
return user.getEmailAddress();
|
||||
return user.getRegistryLockEmailAddress()
|
||||
.orElseThrow(() -> new IllegalArgumentException("User has no registry lock email address"));
|
||||
}
|
||||
|
||||
private String verifyPasswordAndGetEmailLegacyUser(User user, RegistryLockPostInput postInput)
|
||||
|
||||
@@ -149,7 +149,6 @@ public final class TldTest extends EntityTestCase {
|
||||
.setDnsAPlusAaaaTtl(Duration.standardHours(1))
|
||||
.setDnsWriters(ImmutableSet.of("baz", "bang"))
|
||||
// set create billing cost back to the default (database helper sets it to $13)
|
||||
.setCreateBillingCost(Money.of(USD, 8))
|
||||
.setEapFeeSchedule(
|
||||
ImmutableSortedMap.of(
|
||||
START_OF_TIME,
|
||||
@@ -171,7 +170,7 @@ public final class TldTest extends EntityTestCase {
|
||||
|
||||
@Test
|
||||
void testSuccess_tldYamlRoundtrip() throws Exception {
|
||||
Tld testTld = createTld("test").asBuilder().setCreateBillingCost(Money.of(USD, 8)).build();
|
||||
Tld testTld = createTld("test");
|
||||
ObjectMapper mapper = createObjectMapper();
|
||||
String yaml = mapper.writeValueAsString(testTld);
|
||||
Tld constructedTld = mapper.readValue(yaml, Tld.class);
|
||||
@@ -610,15 +609,6 @@ public final class TldTest extends EntityTestCase {
|
||||
assertThat(thrown).hasMessageThat().contains("billing cost cannot be negative");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_negativeCreateBillingCost() {
|
||||
IllegalArgumentException thrown =
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> Tld.get("tld").asBuilder().setCreateBillingCost(Money.of(USD, -42)));
|
||||
assertThat(thrown).hasMessageThat().contains("createBillingCost cannot be negative");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_negativeRestoreBillingCost() {
|
||||
IllegalArgumentException thrown =
|
||||
|
||||
@@ -248,7 +248,6 @@ public final class DatabaseHelper {
|
||||
// Set billing costs to distinct small primes to avoid masking bugs in tests.
|
||||
.setRenewBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 11)))
|
||||
.setEapFeeSchedule(ImmutableSortedMap.of(START_OF_TIME, Money.zero(USD)))
|
||||
.setCreateBillingCost(Money.of(USD, 13))
|
||||
.setCreateBillingCostTransitions(ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 13)))
|
||||
.setRestoreBillingCost(Money.of(USD, 17))
|
||||
.setServerStatusChangeBillingCost(Money.of(USD, 19))
|
||||
|
||||
@@ -176,54 +176,6 @@ public class ConfigureTldCommandTest extends CommandTestCase<ConfigureTldCommand
|
||||
assertThat(updatedTld.getCreateBillingCost(fakeClock.nowUtc())).isEqualTo(Money.of(USD, 25));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fileMissingCreateBillingCostTransitions() throws Exception {
|
||||
createTld("nocreatecostmap");
|
||||
File tldFile = tmpDir.resolve("nocreatecostmap.yaml").toFile();
|
||||
Files.asCharSink(tldFile, UTF_8).write(loadFile(getClass(), "nocreatecostmap.yaml"));
|
||||
runCommandForced("--input=" + tldFile);
|
||||
Tld updatedTld = Tld.get("nocreatecostmap");
|
||||
assertThat(updatedTld.getCreateBillingCostTransitions())
|
||||
.isEqualTo(ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 25)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fileHasCreateBillingCost() throws Exception {
|
||||
createTld("withcreatecost");
|
||||
File tldFile = tmpDir.resolve("withcreatecost.yaml").toFile();
|
||||
Files.asCharSink(tldFile, UTF_8).write(loadFile(getClass(), "withcreatecost.yaml"));
|
||||
runCommandForced("--input=" + tldFile);
|
||||
Tld updatedTld = Tld.get("withcreatecost");
|
||||
assertThat(updatedTld.getCreateBillingCost()).isEqualTo(Money.of(USD, 8));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_fileMissingCreateBillingCostTransitionsRevertsToBasicConstructedMap()
|
||||
throws Exception {
|
||||
ImmutableSortedMap<DateTime, Money> createCostTransitions =
|
||||
ImmutableSortedMap.of(
|
||||
START_OF_TIME,
|
||||
Money.of(USD, 8),
|
||||
fakeClock.nowUtc(),
|
||||
Money.of(USD, 1),
|
||||
fakeClock.nowUtc().plusMonths(1),
|
||||
Money.of(USD, 2),
|
||||
fakeClock.nowUtc().plusMonths(2),
|
||||
Money.of(USD, 3));
|
||||
Tld tld =
|
||||
createTld("nocreatecostmap")
|
||||
.asBuilder()
|
||||
.setCreateBillingCostTransitions(createCostTransitions)
|
||||
.build();
|
||||
assertThat(tld.getCreateBillingCostTransitions().size()).isEqualTo(4);
|
||||
File tldFile = tmpDir.resolve("nocreatecostmap.yaml").toFile();
|
||||
Files.asCharSink(tldFile, UTF_8).write(loadFile(getClass(), "nocreatecostmap.yaml"));
|
||||
runCommandForced("--input=" + tldFile);
|
||||
Tld updatedTld = Tld.get("nocreatecostmap");
|
||||
assertThat(updatedTld.getCreateBillingCostTransitions())
|
||||
.isEqualTo(ImmutableSortedMap.of(START_OF_TIME, Money.of(USD, 25)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_fileMissingNullableFieldsOnCreate() throws Exception {
|
||||
File tldFile = tmpDir.resolve("missingnullablefields.yaml").toFile();
|
||||
@@ -236,20 +188,6 @@ public class ConfigureTldCommandTest extends CommandTestCase<ConfigureTldCommand
|
||||
+ " premiumListName, currency, numDnsPublishLocks]");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_addCreateBillingCostTransitions() throws Exception {
|
||||
createTld("costmap");
|
||||
File tldFile = tmpDir.resolve("costmap.yaml").toFile();
|
||||
Files.asCharSink(tldFile, UTF_8).write(loadFile(getClass(), "costmap.yaml"));
|
||||
runCommandForced("--input=" + tldFile);
|
||||
Tld updatedTld = Tld.get("costmap");
|
||||
ImmutableSortedMap<DateTime, Money> costTransitions =
|
||||
updatedTld.getCreateBillingCostTransitions();
|
||||
assertThat(costTransitions.size()).isEqualTo(3);
|
||||
assertThat(costTransitions.get(START_OF_TIME)).isEqualTo(Money.of(USD, 13));
|
||||
assertThat(costTransitions.get(START_OF_TIME.plusYears(26))).isEqualTo(Money.of(USD, 14));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_fileMissingNullableFieldOnUpdate() throws Exception {
|
||||
Tld tld = createTld("missingnullablefields");
|
||||
|
||||
@@ -53,6 +53,17 @@ public class CreateUserCommandTest extends CommandTestCase<CreateUserCommand> {
|
||||
verifyNoMoreInteractions(iamClient);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_registryLock() throws Exception {
|
||||
runCommandForced(
|
||||
"--email",
|
||||
"user@example.test",
|
||||
"--registry_lock_email_address",
|
||||
"registrylockemail@otherexample.test");
|
||||
assertThat(UserDao.loadUser("user@example.test").get().getRegistryLockEmailAddress())
|
||||
.hasValue("registrylockemail@otherexample.test");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_admin() throws Exception {
|
||||
runCommandForced("--email", "user@example.test", "--admin", "true");
|
||||
@@ -101,4 +112,29 @@ public class CreateUserCommandTest extends CommandTestCase<CreateUserCommand> {
|
||||
.isEqualTo("A user with email user@example.test already exists");
|
||||
verifyNoMoreInteractions(iamClient);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_badEmail() throws Exception {
|
||||
assertThat(
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> runCommandForced("--email", "this is not valid")))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Provided email this is not valid is not a valid email address");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_badRegistryLockEmail() throws Exception {
|
||||
assertThat(
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() ->
|
||||
runCommandForced(
|
||||
"--email",
|
||||
"user@example.test",
|
||||
"--registry_lock_email_address",
|
||||
"this is not valid")))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Provided email this is not valid is not a valid email address");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,6 @@ class GetTldCommandTest extends CommandTestCase<GetTldCommand> {
|
||||
tld.asBuilder()
|
||||
.setDnsAPlusAaaaTtl(Duration.standardMinutes(15))
|
||||
.setDriveFolderId("driveFolder")
|
||||
.setCreateBillingCost(Money.of(USD, 25))
|
||||
.setCreateBillingCostTransitions(
|
||||
ImmutableSortedMap.of(
|
||||
START_OF_TIME,
|
||||
|
||||
@@ -38,6 +38,29 @@ public class UpdateUserCommandTest extends CommandTestCase<UpdateUserCommand> {
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_registryLockEmail() throws Exception {
|
||||
runCommandForced(
|
||||
"--email",
|
||||
"user@example.test",
|
||||
"--registry_lock_email_address",
|
||||
"registrylockemail@otherexample.test");
|
||||
assertThat(UserDao.loadUser("user@example.test").get().getRegistryLockEmailAddress())
|
||||
.hasValue("registrylockemail@otherexample.test");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_removeRegistryLockEmail() throws Exception {
|
||||
UserDao.saveUser(
|
||||
UserDao.loadUser("user@example.test")
|
||||
.get()
|
||||
.asBuilder()
|
||||
.setRegistryLockEmailAddress("registrylock@otherexample.test")
|
||||
.build());
|
||||
runCommandForced("--email", "user@example.test", "--registry_lock_email_address", "");
|
||||
assertThat(UserDao.loadUser("user@example.test").get().getRegistryLockEmailAddress()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_admin() throws Exception {
|
||||
assertThat(UserDao.loadUser("user@example.test").get().getUserRoles().isAdmin()).isFalse();
|
||||
@@ -86,4 +109,19 @@ public class UpdateUserCommandTest extends CommandTestCase<UpdateUserCommand> {
|
||||
.hasMessageThat()
|
||||
.isEqualTo("User nonexistent@example.test not found");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_badRegistryLockEmail() {
|
||||
assertThat(
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() ->
|
||||
runCommandForced(
|
||||
"--email",
|
||||
"user@example.test",
|
||||
"--registry_lock_email_address",
|
||||
"this is not valid")))
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Provided email this is not valid is not a valid email address");
|
||||
}
|
||||
}
|
||||
|
||||
+11
-1
@@ -100,6 +100,7 @@ public class ConsoleRegistryLockActionTest {
|
||||
user =
|
||||
new User.Builder()
|
||||
.setEmailAddress("user@theregistrar.com")
|
||||
.setRegistryLockEmailAddress("registrylock@theregistrar.com")
|
||||
.setUserRoles(
|
||||
new UserRoles.Builder()
|
||||
.setRegistrarRoles(
|
||||
@@ -436,6 +437,15 @@ public class ConsoleRegistryLockActionTest {
|
||||
.isEqualTo("Registry lock not allowed for registrar TheRegistrar");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPost_failure_noRegistryLockEmail() {
|
||||
user = user.asBuilder().setRegistryLockEmailAddress(null).build();
|
||||
action = createDefaultPostAction(true);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(response.getPayload()).isEqualTo("User has no registry lock email address");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPost_failure_badPassword() throws Exception {
|
||||
action = createPostAction("example.test", true, "badPassword", Optional.empty());
|
||||
@@ -534,6 +544,6 @@ public class ConsoleRegistryLockActionTest {
|
||||
assertThat(sentMessage.subject()).matches("Registry (un)?lock verification");
|
||||
assertThat(sentMessage.body()).matches(EMAIL_MESSAGE_TEMPLATE);
|
||||
assertThat(sentMessage.recipients())
|
||||
.containsExactly(new InternetAddress("user@theregistrar.com"));
|
||||
.containsExactly(new InternetAddress("registrylock@theregistrar.com"));
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -218,6 +218,7 @@ final class RegistryLockPostActionTest {
|
||||
google.registry.model.console.User consoleUser =
|
||||
new google.registry.model.console.User.Builder()
|
||||
.setEmailAddress("johndoe@theregistrar.com")
|
||||
.setRegistryLockEmailAddress("johndoe.registrylock@theregistrar.com")
|
||||
.setUserRoles(
|
||||
new UserRoles.Builder()
|
||||
.setRegistrarRoles(
|
||||
@@ -229,7 +230,7 @@ final class RegistryLockPostActionTest {
|
||||
AuthResult consoleAuthResult = AuthResult.createUser(UserAuthInfo.create(consoleUser));
|
||||
action = createAction(consoleAuthResult);
|
||||
Map<String, ?> response = action.handleJsonRequest(lockRequest());
|
||||
assertSuccess(response, "lock", "johndoe@theregistrar.com");
|
||||
assertSuccess(response, "lock", "johndoe.registrylock@theregistrar.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
addGracePeriodLength: "PT432000S"
|
||||
allowedFullyQualifiedHostNames:
|
||||
- "foo"
|
||||
allowedRegistrantContactIds: []
|
||||
anchorTenantAddGracePeriodLength: "PT2592000S"
|
||||
autoRenewGracePeriodLength: "PT3888000S"
|
||||
automaticTransferLength: "PT432000S"
|
||||
claimsPeriodEnd: "294247-01-10T04:00:54.775Z"
|
||||
createBillingCostTransitions:
|
||||
"1970-01-01T00:00:00.000Z":
|
||||
currency: "USD"
|
||||
amount: 13.00
|
||||
"1996-01-01T00:00:00.000Z":
|
||||
currency: "USD"
|
||||
amount: 14.00
|
||||
"2050-01-01T00:00:00.000Z":
|
||||
currency: "USD"
|
||||
amount: 15.00
|
||||
creationTime: "1970-01-01T00:00:00.000Z"
|
||||
currency: "USD"
|
||||
defaultPromoTokens:
|
||||
- "bbbbb"
|
||||
dnsAPlusAaaaTtl: "PT3600S"
|
||||
dnsDsTtl: null
|
||||
dnsNsTtl: null
|
||||
dnsPaused: false
|
||||
dnsWriters:
|
||||
- "VoidDnsWriter"
|
||||
driveFolderId: null
|
||||
eapFeeSchedule:
|
||||
"1970-01-01T00:00:00.000Z":
|
||||
currency: "USD"
|
||||
amount: 0.00
|
||||
"2000-06-01T00:00:00.000Z":
|
||||
currency: "USD"
|
||||
amount: 100.00
|
||||
"2000-06-02T00:00:00.000Z":
|
||||
currency: "USD"
|
||||
amount: 0.00
|
||||
escrowEnabled: false
|
||||
idnTables:
|
||||
- "EXTENDED_LATIN"
|
||||
- "JA"
|
||||
invoicingEnabled: false
|
||||
lordnUsername: null
|
||||
numDnsPublishLocks: 1
|
||||
pendingDeleteLength: "PT432000S"
|
||||
premiumListName: "test"
|
||||
pricingEngineClassName: "google.registry.model.pricing.StaticPremiumListPricingEngine"
|
||||
redemptionGracePeriodLength: "PT2592000S"
|
||||
registryLockOrUnlockBillingCost:
|
||||
currency: "USD"
|
||||
amount: 0.00
|
||||
renewBillingCostTransitions:
|
||||
"1970-01-01T00:00:00.000Z":
|
||||
currency: "USD"
|
||||
amount: 11.00
|
||||
renewGracePeriodLength: "PT432000S"
|
||||
reservedListNames: []
|
||||
restoreBillingCost:
|
||||
currency: "USD"
|
||||
amount: 17.00
|
||||
roidSuffix: "COSTMAP"
|
||||
serverStatusChangeBillingCost:
|
||||
currency: "USD"
|
||||
amount: 19.00
|
||||
tldStateTransitions:
|
||||
"1970-01-01T00:00:00.000Z": "GENERAL_AVAILABILITY"
|
||||
tldStr: "costmap"
|
||||
tldType: "REAL"
|
||||
tldUnicode: "costmap"
|
||||
transferGracePeriodLength: "PT432000S"
|
||||
@@ -1,56 +0,0 @@
|
||||
addGracePeriodLength: "PT432000S"
|
||||
allowedFullyQualifiedHostNames: []
|
||||
allowedRegistrantContactIds: []
|
||||
anchorTenantAddGracePeriodLength: "PT2592000S"
|
||||
autoRenewGracePeriodLength: "PT3888000S"
|
||||
automaticTransferLength: "PT432000S"
|
||||
claimsPeriodEnd: "294247-01-10T04:00:54.775Z"
|
||||
createBillingCostTransitions:
|
||||
"1970-01-01T00:00:00.000Z":
|
||||
currency: "USD"
|
||||
amount: 25.00
|
||||
creationTime: "2022-09-01T00:00:00.000Z"
|
||||
currency: "USD"
|
||||
defaultPromoTokens: []
|
||||
dnsAPlusAaaaTtl: "PT900S"
|
||||
dnsDsTtl: null
|
||||
dnsNsTtl: null
|
||||
dnsPaused: false
|
||||
dnsWriters:
|
||||
- "VoidDnsWriter"
|
||||
driveFolderId: "driveFolder"
|
||||
eapFeeSchedule:
|
||||
"1970-01-01T00:00:00.000Z":
|
||||
currency: "USD"
|
||||
amount: 0.00
|
||||
escrowEnabled: false
|
||||
idnTables: []
|
||||
invoicingEnabled: false
|
||||
lordnUsername: null
|
||||
numDnsPublishLocks: 1
|
||||
pendingDeleteLength: "PT432000S"
|
||||
premiumListName: "test"
|
||||
pricingEngineClassName: "google.registry.model.pricing.StaticPremiumListPricingEngine"
|
||||
redemptionGracePeriodLength: "PT2592000S"
|
||||
registryLockOrUnlockBillingCost:
|
||||
currency: "USD"
|
||||
amount: 0.00
|
||||
renewBillingCostTransitions:
|
||||
"1970-01-01T00:00:00.000Z":
|
||||
currency: "USD"
|
||||
amount: 11.00
|
||||
renewGracePeriodLength: "PT432000S"
|
||||
reservedListNames: []
|
||||
restoreBillingCost:
|
||||
currency: "USD"
|
||||
amount: 17.00
|
||||
roidSuffix: "NOCREATE"
|
||||
serverStatusChangeBillingCost:
|
||||
currency: "USD"
|
||||
amount: 19.00
|
||||
tldStateTransitions:
|
||||
"1970-01-01T00:00:00.000Z": "GENERAL_AVAILABILITY"
|
||||
tldStr: "nocreatecostmap"
|
||||
tldType: "REAL"
|
||||
tldUnicode: "nocreatecostmap"
|
||||
transferGracePeriodLength: "PT432000S"
|
||||
@@ -1,62 +0,0 @@
|
||||
addGracePeriodLength: "PT432000S"
|
||||
allowedFullyQualifiedHostNames: []
|
||||
allowedRegistrantContactIds: []
|
||||
anchorTenantAddGracePeriodLength: "PT2592000S"
|
||||
autoRenewGracePeriodLength: "PT3888000S"
|
||||
automaticTransferLength: "PT432000S"
|
||||
claimsPeriodEnd: "294247-01-10T04:00:54.775Z"
|
||||
createBillingCost:
|
||||
currency: "USD"
|
||||
amount: 25.00
|
||||
createBillingCostTransitions:
|
||||
"1970-01-01T00:00:00.000Z":
|
||||
currency: "USD"
|
||||
amount: 8.00
|
||||
"2020-01-01T00:00:00.000Z":
|
||||
currency: "USD"
|
||||
amount: 25.00
|
||||
creationTime: "2022-09-01T00:00:00.000Z"
|
||||
currency: "USD"
|
||||
defaultPromoTokens: []
|
||||
dnsAPlusAaaaTtl: "PT900S"
|
||||
dnsDsTtl: null
|
||||
dnsNsTtl: null
|
||||
dnsPaused: false
|
||||
dnsWriters:
|
||||
- "VoidDnsWriter"
|
||||
driveFolderId: "driveFolder"
|
||||
eapFeeSchedule:
|
||||
"1970-01-01T00:00:00.000Z":
|
||||
currency: "USD"
|
||||
amount: 0.00
|
||||
escrowEnabled: false
|
||||
idnTables: []
|
||||
invoicingEnabled: false
|
||||
lordnUsername: null
|
||||
numDnsPublishLocks: 1
|
||||
pendingDeleteLength: "PT432000S"
|
||||
premiumListName: "test"
|
||||
pricingEngineClassName: "google.registry.model.pricing.StaticPremiumListPricingEngine"
|
||||
redemptionGracePeriodLength: "PT2592000S"
|
||||
registryLockOrUnlockBillingCost:
|
||||
currency: "USD"
|
||||
amount: 0.00
|
||||
renewBillingCostTransitions:
|
||||
"1970-01-01T00:00:00.000Z":
|
||||
currency: "USD"
|
||||
amount: 11.00
|
||||
renewGracePeriodLength: "PT432000S"
|
||||
reservedListNames: []
|
||||
restoreBillingCost:
|
||||
currency: "USD"
|
||||
amount: 17.00
|
||||
roidSuffix: "TLD"
|
||||
serverStatusChangeBillingCost:
|
||||
currency: "USD"
|
||||
amount: 19.00
|
||||
tldStateTransitions:
|
||||
"1970-01-01T00:00:00.000Z": "GENERAL_AVAILABILITY"
|
||||
tldStr: "withcreatecost"
|
||||
tldType: "REAL"
|
||||
tldUnicode: "withcreatecost"
|
||||
transferGracePeriodLength: "PT432000S"
|
||||
@@ -261,7 +261,7 @@ td.section {
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="property_name">generated on</td>
|
||||
<td class="property_value">2024-05-01 21:04:48.5296048</td>
|
||||
<td class="property_value">2024-05-09 17:59:02.29076074</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="property_name">last flyway file</td>
|
||||
@@ -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="3745" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">generated by</text>
|
||||
<text text-anchor="start" x="3828" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">SchemaCrawler 16.10.1</text>
|
||||
<text text-anchor="start" x="3744" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">generated on</text>
|
||||
<text text-anchor="start" x="3828" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">2024-05-01 21:04:48.5296048</text>
|
||||
<polygon fill="none" stroke="#888888" points="3741,-4 3741,-44 4013,-44 4013,-4 3741,-4" /> <!-- allocationtoken_a08ccbef -->
|
||||
<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 -->
|
||||
<g id="node1" class="node">
|
||||
<title>
|
||||
allocationtoken_a08ccbef
|
||||
|
||||
@@ -261,7 +261,7 @@ td.section {
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="property_name">generated on</td>
|
||||
<td class="property_value">2024-05-01 21:04:45.792776047</td>
|
||||
<td class="property_value">2024-05-09 17:58:59.761656939</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="property_name">last flyway file</td>
|
||||
@@ -280,7 +280,7 @@ td.section {
|
||||
<text text-anchor="start" x="4443.5" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">generated by</text>
|
||||
<text text-anchor="start" x="4526.5" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">SchemaCrawler 16.10.1</text>
|
||||
<text text-anchor="start" x="4442.5" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">generated on</text>
|
||||
<text text-anchor="start" x="4526.5" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">2024-05-01 21:04:45.792776047</text>
|
||||
<text text-anchor="start" x="4526.5" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">2024-05-09 17:58:59.761656939</text>
|
||||
<polygon fill="none" stroke="#888888" points="4439,-4 4439,-44 4726,-44 4726,-4 4439,-4" /> <!-- allocationtoken_a08ccbef -->
|
||||
<g id="node1" class="node">
|
||||
<title>
|
||||
|
||||
@@ -833,8 +833,6 @@
|
||||
breakglass_mode boolean not null,
|
||||
bsa_enroll_start_time timestamptz,
|
||||
claims_period_end timestamptz not null,
|
||||
create_billing_cost_amount numeric(19, 2),
|
||||
create_billing_cost_currency text,
|
||||
create_billing_cost_transitions hstore not null,
|
||||
creation_time timestamptz not null,
|
||||
currency text not null,
|
||||
@@ -884,6 +882,7 @@
|
||||
id bigserial not null,
|
||||
update_timestamp timestamptz,
|
||||
email_address text not null,
|
||||
registry_lock_email_address text,
|
||||
registry_lock_password_hash text,
|
||||
registry_lock_password_salt text,
|
||||
global_role text not null,
|
||||
@@ -901,6 +900,7 @@
|
||||
history_url text not null,
|
||||
user_id int8 not null,
|
||||
email_address text not null,
|
||||
registry_lock_email_address text,
|
||||
registry_lock_password_hash text,
|
||||
registry_lock_password_salt text,
|
||||
global_role text not null,
|
||||
|
||||
Reference in New Issue
Block a user