Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fd7820759d | |||
| 69359bb1e6 | |||
| 35b602a76e | |||
| 82002d1f75 | |||
| 2fd9b062df | |||
| ec3804e87e | |||
| d0d28cc7e6 | |||
| 2d1260c01b | |||
| 06da6a2cc6 | |||
| 858a22f82e | |||
| 3c126ddfd4 | |||
| 2b98e6f177 | |||
| 20036b6a74 | |||
| 396cbd6bd3 | |||
| 71ea16ff69 | |||
| 45331be166 |
@@ -6451,9 +6451,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
|
||||
"integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
|
||||
"version": "1.7.4",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz",
|
||||
"integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
|
||||
@@ -18,7 +18,11 @@
|
||||
<mat-icon>edit</mat-icon>
|
||||
Edit
|
||||
</button>
|
||||
<button mat-icon-button aria-label="Delete Contact">
|
||||
<button
|
||||
mat-icon-button
|
||||
aria-label="Delete Contact"
|
||||
(click)="deleteContact()"
|
||||
>
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
}
|
||||
|
||||
@@ -50,6 +50,9 @@ export class ContactDetailsComponent {
|
||||
error: (err: HttpErrorResponse) => {
|
||||
this._snackBar.open(err.error);
|
||||
},
|
||||
complete: () => {
|
||||
this.goBack();
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,6 +132,18 @@
|
||||
/>
|
||||
</mat-form-field>
|
||||
|
||||
@if((userDataService.userData()?.globalRole || 'NONE') !== "NONE") {
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>ICANN Referral Email: </mat-label>
|
||||
<input
|
||||
matInput
|
||||
type="text"
|
||||
[(ngModel)]="registrarInEdit.icannReferralEmail"
|
||||
[ngModelOptions]="{ standalone: true }"
|
||||
/>
|
||||
</mat-form-field>
|
||||
}
|
||||
|
||||
<button mat-flat-button color="primary" type="submit">Save</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
Registrar,
|
||||
RegistrarService,
|
||||
} from 'src/app/registrar/registrar.service';
|
||||
import { UserDataService } from 'src/app/shared/services/userData.service';
|
||||
import { WhoisService } from './whois.service';
|
||||
|
||||
@Component({
|
||||
@@ -30,6 +31,7 @@ export default class WhoisEditComponent {
|
||||
registrarInEdit: Registrar | undefined;
|
||||
|
||||
constructor(
|
||||
public userDataService: UserDataService,
|
||||
public whoisService: WhoisService,
|
||||
public registrarService: RegistrarService,
|
||||
private _snackBar: MatSnackBar
|
||||
|
||||
@@ -77,6 +77,7 @@ public class CloudTasksUtils implements Serializable {
|
||||
@Config("projectId") String projectId,
|
||||
@Config("locationId") String locationId,
|
||||
@Config("oauthClientId") String oauthClientId,
|
||||
// Note that this has to be a service account, due to limitations of the Cloud Tasks API.
|
||||
@ApplicationDefaultCredential GoogleCredentialsBundle credential,
|
||||
SerializableCloudTasksClient client) {
|
||||
this.retrier = retrier;
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<delete>
|
||||
<domain:delete
|
||||
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>%DOMAIN%</domain:name>
|
||||
</domain:delete>
|
||||
</delete>
|
||||
<extension>
|
||||
<metadata:metadata xmlns:metadata="urn:google:params:xml:ns:metadata-1.0">
|
||||
<metadata:reason>Non-renewing domain has reached expiration date.</metadata:reason>
|
||||
<metadata:requestedByRegistrar>false</metadata:requestedByRegistrar>
|
||||
</metadata:metadata>
|
||||
</extension>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
@@ -365,7 +365,7 @@ public final class DomainCreateFlow implements MutatingFlow {
|
||||
createAutorenewBillingEvent(
|
||||
domainHistoryId,
|
||||
registrationExpirationTime,
|
||||
getRenewalPriceInfo(isAnchorTenant, allocationToken, feesAndCredits));
|
||||
getRenewalPriceInfo(isAnchorTenant, allocationToken));
|
||||
PollMessage.Autorenew autorenewPollMessage =
|
||||
createAutorenewPollMessage(domainHistoryId, registrationExpirationTime);
|
||||
ImmutableSet.Builder<ImmutableObject> entitiesToSave = new ImmutableSet.Builder<>();
|
||||
@@ -688,9 +688,7 @@ public final class DomainCreateFlow implements MutatingFlow {
|
||||
* AllocationToken} is 'SPECIFIED'.
|
||||
*/
|
||||
static RenewalPriceInfo getRenewalPriceInfo(
|
||||
boolean isAnchorTenant,
|
||||
Optional<AllocationToken> allocationToken,
|
||||
FeesAndCredits feesAndCredits) {
|
||||
boolean isAnchorTenant, Optional<AllocationToken> allocationToken) {
|
||||
if (isAnchorTenant) {
|
||||
allocationToken.ifPresent(
|
||||
token ->
|
||||
@@ -701,7 +699,7 @@ public final class DomainCreateFlow implements MutatingFlow {
|
||||
} else if (allocationToken.isPresent()
|
||||
&& allocationToken.get().getRenewalPriceBehavior() == RenewalPriceBehavior.SPECIFIED) {
|
||||
return RenewalPriceInfo.create(
|
||||
RenewalPriceBehavior.SPECIFIED, feesAndCredits.getCreateCost());
|
||||
RenewalPriceBehavior.SPECIFIED, allocationToken.get().getRenewalPrice().get());
|
||||
} else {
|
||||
return RenewalPriceInfo.create(RenewalPriceBehavior.DEFAULT, null);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
package google.registry.flows.domain;
|
||||
|
||||
import static com.google.common.base.MoreObjects.firstNonNull;
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet;
|
||||
import static com.google.common.collect.Sets.symmetricDifference;
|
||||
@@ -282,7 +281,7 @@ public final class DomainUpdateFlow implements MutatingFlow {
|
||||
.removeContacts(remove.getContacts())
|
||||
.addContacts(add.getContacts())
|
||||
.setRegistrant(determineUpdatedRegistrant(change, domain))
|
||||
.setAuthInfo(firstNonNull(change.getAuthInfo(), domain.getAuthInfo()));
|
||||
.setAuthInfo(Optional.ofNullable(change.getAuthInfo()).orElse(domain.getAuthInfo()));
|
||||
|
||||
if (!add.getNameservers().isEmpty()) {
|
||||
domainBuilder.addNameservers(add.getNameservers().stream().collect(toImmutableSet()));
|
||||
|
||||
@@ -32,7 +32,6 @@ import com.google.common.collect.Streams;
|
||||
import google.registry.batch.CloudTasksUtils;
|
||||
import google.registry.model.console.RegistrarRole;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.model.console.UserDao;
|
||||
import google.registry.model.console.UserRoles;
|
||||
import google.registry.model.pricing.StaticPremiumListPricingEngine;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
@@ -48,9 +47,7 @@ import google.registry.util.CidrAddressBlock;
|
||||
import google.registry.util.RegistryEnvironment;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -271,29 +268,21 @@ public final class OteAccountBuilder {
|
||||
Optional<String> groupEmailAddress, CloudTasksUtils cloudTasksUtils, IamClient iamClient) {
|
||||
for (User user : users) {
|
||||
User.grantIapPermission(
|
||||
user.getEmailAddress(), groupEmailAddress, cloudTasksUtils, iamClient);
|
||||
user.getEmailAddress(), groupEmailAddress, cloudTasksUtils, null, iamClient);
|
||||
}
|
||||
}
|
||||
|
||||
/** Saves all the OT&E entities we created. */
|
||||
private void saveAllEntities() {
|
||||
ImmutableList<Tld> registries = ImmutableList.of(sunriseTld, gaTld, eapTld);
|
||||
Map<String, User> existingUsers = new HashMap<>();
|
||||
|
||||
users.forEach(
|
||||
user ->
|
||||
UserDao.loadUser(user.getEmailAddress())
|
||||
.ifPresent(
|
||||
existingUser ->
|
||||
existingUsers.put(existingUser.getEmailAddress(), existingUser)));
|
||||
|
||||
if (!replaceExisting) {
|
||||
checkState(existingUsers.isEmpty(), "Found existing users: %s", existingUsers);
|
||||
}
|
||||
|
||||
tm().transact(
|
||||
() -> {
|
||||
if (!replaceExisting) {
|
||||
ImmutableMap<String, User> existingUsers =
|
||||
tm().loadByEntitiesIfPresent(users).stream()
|
||||
.collect(toImmutableMap(User::getEmailAddress, u -> u));
|
||||
checkState(existingUsers.isEmpty(), "Found existing users: %s", existingUsers);
|
||||
|
||||
ImmutableList<VKey<? extends ImmutableObject>> keys =
|
||||
Streams.concat(
|
||||
registries.stream().map(tld -> Tld.createVKey(tld.getTldStr())),
|
||||
@@ -317,16 +306,7 @@ public final class OteAccountBuilder {
|
||||
tm().putAll(registrars);
|
||||
});
|
||||
|
||||
for (User user : users) {
|
||||
String email = user.getEmailAddress();
|
||||
if (existingUsers.containsKey(email)) {
|
||||
// Note that other roles for the existing user are reset. We do this instead of simply
|
||||
// saving the new user is that UserDao does not allow us to save the new user with the same
|
||||
// email as the existing user.
|
||||
user = existingUsers.get(email).asBuilder().setUserRoles(user.getUserRoles()).build();
|
||||
}
|
||||
UserDao.saveUser(user);
|
||||
}
|
||||
tm().transact(() -> tm().putAll(ImmutableList.copyOf(users)));
|
||||
}
|
||||
|
||||
private Registrar addAllowedTld(Registrar registrar) {
|
||||
|
||||
@@ -14,22 +14,25 @@
|
||||
|
||||
package google.registry.model.console;
|
||||
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static google.registry.tools.server.UpdateUserGroupAction.GROUP_UPDATE_QUEUE;
|
||||
|
||||
import com.google.cloud.tasks.v2.Task;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.google.common.net.MediaType;
|
||||
import google.registry.batch.CloudTasksUtils;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.request.Action.Service;
|
||||
import google.registry.tools.IamClient;
|
||||
import google.registry.tools.ServiceConnection;
|
||||
import google.registry.tools.server.UpdateUserGroupAction;
|
||||
import google.registry.tools.server.UpdateUserGroupAction.Mode;
|
||||
import google.registry.util.RegistryEnvironment;
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.AccessType;
|
||||
import javax.persistence.Embeddable;
|
||||
@@ -46,8 +49,6 @@ public class User extends UserBase {
|
||||
public static final String IAP_SECURED_WEB_APP_USER_ROLE = "roles/iap.httpsResourceAccessor";
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
|
||||
@VisibleForTesting public static final AtomicLong ID_GENERATOR_FOR_TESTING = new AtomicLong();
|
||||
|
||||
/**
|
||||
* Grants the user permission to pass IAP.
|
||||
*
|
||||
@@ -57,18 +58,30 @@ public class User extends UserBase {
|
||||
public static void grantIapPermission(
|
||||
String emailAddress,
|
||||
Optional<String> groupEmailAddress,
|
||||
CloudTasksUtils cloudTasksUtils,
|
||||
@Nullable CloudTasksUtils cloudTasksUtils,
|
||||
@Nullable ServiceConnection connection,
|
||||
IamClient iamClient) {
|
||||
if (RegistryEnvironment.isInTestServer()) {
|
||||
return;
|
||||
}
|
||||
checkArgument(
|
||||
cloudTasksUtils != null || connection != null,
|
||||
"At least one of cloudTasksUtils or connection must be set");
|
||||
checkArgument(
|
||||
cloudTasksUtils == null || connection == null,
|
||||
"Only one of cloudTasksUtils or connection can be set");
|
||||
if (groupEmailAddress.isEmpty()) {
|
||||
logger.atInfo().log("Granting IAP role to user %s", emailAddress);
|
||||
iamClient.addBinding(emailAddress, IAP_SECURED_WEB_APP_USER_ROLE);
|
||||
} else {
|
||||
logger.atInfo().log("Adding %s to group %s", emailAddress, groupEmailAddress.get());
|
||||
modifyGroupMembershipAsync(
|
||||
emailAddress, groupEmailAddress.get(), cloudTasksUtils, UpdateUserGroupAction.Mode.ADD);
|
||||
if (cloudTasksUtils != null) {
|
||||
modifyGroupMembershipAsync(
|
||||
emailAddress, groupEmailAddress.get(), cloudTasksUtils, UpdateUserGroupAction.Mode.ADD);
|
||||
} else {
|
||||
modifyGroupMembershipSync(
|
||||
emailAddress, groupEmailAddress.get(), connection, UpdateUserGroupAction.Mode.ADD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,18 +94,29 @@ public class User extends UserBase {
|
||||
public static void revokeIapPermission(
|
||||
String emailAddress,
|
||||
Optional<String> groupEmailAddress,
|
||||
CloudTasksUtils cloudTasksUtils,
|
||||
@Nullable CloudTasksUtils cloudTasksUtils,
|
||||
@Nullable ServiceConnection connection,
|
||||
IamClient iamClient) {
|
||||
if (RegistryEnvironment.isInTestServer()) {
|
||||
return;
|
||||
}
|
||||
checkArgument(
|
||||
cloudTasksUtils != null || connection != null,
|
||||
"At least one of cloudTasksUtils or connection must be set");
|
||||
checkArgument(
|
||||
cloudTasksUtils == null || connection == null,
|
||||
"Only one of cloudTasksUtils or connection can be set");
|
||||
if (groupEmailAddress.isEmpty()) {
|
||||
logger.atInfo().log("Removing IAP role from user %s", emailAddress);
|
||||
iamClient.removeBinding(emailAddress, IAP_SECURED_WEB_APP_USER_ROLE);
|
||||
} else {
|
||||
logger.atInfo().log("Removing %s from group %s", emailAddress, groupEmailAddress.get());
|
||||
modifyGroupMembershipAsync(
|
||||
emailAddress, groupEmailAddress.get(), cloudTasksUtils, Mode.REMOVE);
|
||||
if (cloudTasksUtils != null) {
|
||||
modifyGroupMembershipAsync(
|
||||
emailAddress, groupEmailAddress.get(), cloudTasksUtils, Mode.REMOVE);
|
||||
} else {
|
||||
modifyGroupMembershipSync(emailAddress, groupEmailAddress.get(), connection, Mode.REMOVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,10 +139,23 @@ public class User extends UserBase {
|
||||
cloudTasksUtils.enqueue(GROUP_UPDATE_QUEUE, task);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Access(AccessType.PROPERTY)
|
||||
public Long getId() {
|
||||
return super.getId();
|
||||
private static void modifyGroupMembershipSync(
|
||||
String userEmailAddress, String groupEmailAddress, ServiceConnection connection, Mode mode) {
|
||||
try {
|
||||
connection.sendPostRequest(
|
||||
UpdateUserGroupAction.PATH,
|
||||
ImmutableMap.of(
|
||||
"userEmailAddress",
|
||||
userEmailAddress,
|
||||
"groupEmailAddress",
|
||||
groupEmailAddress,
|
||||
"groupUpdateMode",
|
||||
mode.name()),
|
||||
MediaType.PLAIN_TEXT_UTF_8,
|
||||
new byte[0]);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Cannot send request to server", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Id
|
||||
@@ -135,7 +172,7 @@ public class User extends UserBase {
|
||||
|
||||
@Override
|
||||
public VKey<User> createVKey() {
|
||||
return VKey.create(User.class, getId());
|
||||
return VKey.create(User.class, getEmailAddress());
|
||||
}
|
||||
|
||||
/** Builder for constructing immutable {@link User} objects. */
|
||||
@@ -146,20 +183,5 @@ public class User extends UserBase {
|
||||
public Builder(User user) {
|
||||
super(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User build() {
|
||||
// Sets the ID temporarily until we can get rid of the non-null constraint (and the field)
|
||||
if (getInstance().getId() == null || getInstance().getId().equals(0L)) {
|
||||
// In tests, we cannot guarantee that the database is fully set up -- so don't use it to
|
||||
// generate a new long
|
||||
if (RegistryEnvironment.get() == RegistryEnvironment.UNITTEST) {
|
||||
getInstance().setId(ID_GENERATOR_FOR_TESTING.getAndIncrement());
|
||||
} else {
|
||||
getInstance().setId(tm().reTransact(tm()::allocateId));
|
||||
}
|
||||
}
|
||||
return super.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,9 +49,6 @@ public class UserBase extends UpdateAutoTimestampEntity implements Buildable {
|
||||
|
||||
private static final long serialVersionUID = 6936728603828566721L;
|
||||
|
||||
/** Autogenerated unique ID of this user. */
|
||||
@Transient private Long id;
|
||||
|
||||
/** Email address of the user in question. */
|
||||
@Transient String emailAddress;
|
||||
|
||||
@@ -71,24 +68,15 @@ public class UserBase extends UpdateAutoTimestampEntity implements Buildable {
|
||||
/** Randomly generated hash salt. */
|
||||
String registryLockPasswordSalt;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the user ID.
|
||||
* Sets the user email address.
|
||||
*
|
||||
* <p>This should only be used for restoring the user id of an object being loaded in a PostLoad
|
||||
* method (effectively, when it is still under construction by Hibernate). In all other cases, the
|
||||
* object should be regarded as immutable and changes should go through a Builder.
|
||||
* <p>This should only be used for restoring an object being loaded in a PostLoad method
|
||||
* (effectively, when it is still under construction by Hibernate). In all other cases, the object
|
||||
* should be regarded as immutable and changes should go through a Builder.
|
||||
*
|
||||
* <p>In addition to this special case use, this method must exist to satisfy Hibernate.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
void setEmailAddress(String emailAddress) {
|
||||
this.emailAddress = emailAddress;
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
// Copyright 2022 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.model.console;
|
||||
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/** Data access object for {@link User} objects to simplify saving and retrieval. */
|
||||
public class UserDao {
|
||||
|
||||
/** Retrieves the one user with this email address if it exists. */
|
||||
public static Optional<User> loadUser(String emailAddress) {
|
||||
return tm().transact(
|
||||
() ->
|
||||
tm().query("FROM User WHERE emailAddress = :emailAddress", User.class)
|
||||
.setParameter("emailAddress", emailAddress)
|
||||
.getResultStream()
|
||||
.findFirst());
|
||||
}
|
||||
|
||||
/** Saves the given user, updating it if it already exists. */
|
||||
public static void saveUser(User user) {
|
||||
tm().transact(() -> tm().put(user));
|
||||
}
|
||||
}
|
||||
@@ -38,10 +38,6 @@ public class UserUpdateHistory extends ConsoleUpdateHistory {
|
||||
|
||||
UserBase user;
|
||||
|
||||
// This field exists so that it's populated in the SQL table
|
||||
@Column(nullable = false, name = "userId")
|
||||
Long id;
|
||||
|
||||
@Column(nullable = false, name = "emailAddress")
|
||||
String emailAddress;
|
||||
|
||||
@@ -51,7 +47,6 @@ public class UserUpdateHistory extends ConsoleUpdateHistory {
|
||||
|
||||
@PostLoad
|
||||
void postLoad() {
|
||||
user.setId(id);
|
||||
user.setEmailAddress(emailAddress);
|
||||
}
|
||||
|
||||
@@ -83,7 +78,6 @@ public class UserUpdateHistory extends ConsoleUpdateHistory {
|
||||
|
||||
public Builder setUser(User user) {
|
||||
getInstance().user = user;
|
||||
getInstance().id = user.getId();
|
||||
getInstance().emailAddress = user.getEmailAddress();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -144,6 +144,7 @@ public class DomainBase extends EppResource
|
||||
@AttributeOverride(name = "pw.value", column = @Column(name = "auth_info_value")),
|
||||
@AttributeOverride(name = "pw.repoId", column = @Column(name = "auth_info_repo_id")),
|
||||
})
|
||||
@Nullable
|
||||
DomainAuthInfo authInfo;
|
||||
|
||||
/** Data used to construct DS records for this domain. */
|
||||
@@ -620,6 +621,7 @@ public class DomainBase extends EppResource
|
||||
return getAllContacts(true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public DomainAuthInfo getAuthInfo() {
|
||||
return authInfo;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ package google.registry.model.eppcommon;
|
||||
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
@@ -49,10 +50,12 @@ public abstract class AuthInfo extends ImmutableObject implements UnsafeSerializ
|
||||
public static class PasswordAuth extends ImmutableObject implements UnsafeSerializable {
|
||||
@XmlValue
|
||||
@XmlJavaTypeAdapter(NormalizedStringAdapter.class)
|
||||
@Nullable
|
||||
String value;
|
||||
|
||||
@XmlAttribute(name = "roid")
|
||||
@XmlJavaTypeAdapter(CollapsedStringAdapter.class)
|
||||
@Nullable
|
||||
String repoId;
|
||||
|
||||
public String getValue() {
|
||||
@@ -63,14 +66,14 @@ public abstract class AuthInfo extends ImmutableObject implements UnsafeSerializ
|
||||
return repoId;
|
||||
}
|
||||
|
||||
public static PasswordAuth create(String value, String repoId) {
|
||||
public static PasswordAuth create(@Nullable String value, @Nullable String repoId) {
|
||||
PasswordAuth instance = new PasswordAuth();
|
||||
instance.value = value;
|
||||
instance.repoId = repoId;
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static PasswordAuth create(String value) {
|
||||
public static PasswordAuth create(@Nullable String value) {
|
||||
return create(value, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package google.registry.request.auth;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.google.api.client.json.webtoken.JsonWebSignature;
|
||||
import com.google.auth.oauth2.TokenVerifier;
|
||||
@@ -23,7 +24,7 @@ import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import google.registry.config.RegistryConfig.Config;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.model.console.UserDao;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.request.auth.AuthModule.IapOidc;
|
||||
import google.registry.request.auth.AuthModule.RegularOidc;
|
||||
import google.registry.request.auth.AuthModule.RegularOidcFallback;
|
||||
@@ -117,7 +118,8 @@ public abstract class OidcTokenAuthenticationMechanism implements Authentication
|
||||
logger.atWarning().log("No email address from the OIDC token:\n%s", token.getPayload());
|
||||
return AuthResult.NOT_AUTHENTICATED;
|
||||
}
|
||||
Optional<User> maybeUser = UserDao.loadUser(email);
|
||||
Optional<User> maybeUser =
|
||||
tm().transact(() -> tm().loadByKeyIfPresent(VKey.create(User.class, email)));
|
||||
if (maybeUser.isPresent()) {
|
||||
return AuthResult.createUser(maybeUser.get());
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import com.google.common.collect.ImmutableMap;
|
||||
import google.registry.model.console.GlobalRole;
|
||||
import google.registry.model.console.RegistrarRole;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.model.console.UserDao;
|
||||
import google.registry.model.console.UserRoles;
|
||||
import google.registry.tools.params.KeyValueMapParameter.StringToRegistrarRoleMap;
|
||||
import java.util.Optional;
|
||||
@@ -95,8 +94,6 @@ public abstract class CreateOrUpdateUserCommand extends ConfirmingCommand {
|
||||
builder.setRegistryLockEmailAddress(registryLockEmailAddress);
|
||||
}
|
||||
}
|
||||
|
||||
User newUser = builder.build();
|
||||
UserDao.saveUser(newUser);
|
||||
tm().put(builder.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,24 +16,24 @@ package google.registry.tools;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static google.registry.model.console.User.grantIapPermission;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.beust.jcommander.Parameters;
|
||||
import google.registry.batch.CloudTasksUtils;
|
||||
import google.registry.config.RegistryConfig.Config;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.model.console.UserDao;
|
||||
import google.registry.persistence.VKey;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/** Command to create a new User. */
|
||||
@Parameters(separators = " =", commandDescription = "Update a user account")
|
||||
public class CreateUserCommand extends CreateOrUpdateUserCommand {
|
||||
public class CreateUserCommand extends CreateOrUpdateUserCommand implements CommandWithConnection {
|
||||
|
||||
private ServiceConnection connection;
|
||||
|
||||
@Inject IamClient iamClient;
|
||||
|
||||
@Inject CloudTasksUtils cloudTasksUtils;
|
||||
|
||||
@Inject
|
||||
@Config("gSuiteConsoleUserGroupEmailAddress")
|
||||
Optional<String> maybeGroupEmailAddress;
|
||||
@@ -41,14 +41,20 @@ public class CreateUserCommand extends CreateOrUpdateUserCommand {
|
||||
@Nullable
|
||||
@Override
|
||||
User getExistingUser(String email) {
|
||||
checkArgument(UserDao.loadUser(email).isEmpty(), "A user with email %s already exists", email);
|
||||
checkArgument(
|
||||
!tm().exists(VKey.create(User.class, email)), "A user with email %s already exists", email);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String execute() throws Exception {
|
||||
String ret = super.execute();
|
||||
grantIapPermission(email, maybeGroupEmailAddress, cloudTasksUtils, iamClient);
|
||||
grantIapPermission(email, maybeGroupEmailAddress, null, connection, iamClient);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConnection(ServiceConnection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,28 +14,27 @@
|
||||
|
||||
package google.registry.tools;
|
||||
|
||||
import static com.google.api.client.util.Preconditions.checkArgument;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
import static google.registry.util.PreconditionsUtils.checkArgumentPresent;
|
||||
|
||||
import com.beust.jcommander.Parameter;
|
||||
import com.beust.jcommander.Parameters;
|
||||
import google.registry.batch.CloudTasksUtils;
|
||||
import google.registry.config.RegistryConfig.Config;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.model.console.UserDao;
|
||||
import google.registry.persistence.VKey;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/** Deletes a {@link User}. */
|
||||
@Parameters(separators = " =", commandDescription = "Delete a user account")
|
||||
public class DeleteUserCommand extends ConfirmingCommand {
|
||||
public class DeleteUserCommand extends ConfirmingCommand implements CommandWithConnection {
|
||||
|
||||
private ServiceConnection connection;
|
||||
|
||||
@Inject IamClient iamClient;
|
||||
|
||||
@Inject CloudTasksUtils cloudTasksUtils;
|
||||
|
||||
@Inject
|
||||
@Config("gSuiteConsoleUserGroupEmailAddress")
|
||||
Optional<String> maybeGroupEmailAddress;
|
||||
@@ -47,7 +46,9 @@ public class DeleteUserCommand extends ConfirmingCommand {
|
||||
@Override
|
||||
protected String prompt() {
|
||||
checkArgumentNotNull(email, "Email must be provided");
|
||||
checkArgumentPresent(UserDao.loadUser(email), "Email does not correspond to a valid user");
|
||||
checkArgument(
|
||||
tm().transact(() -> tm().exists(VKey.create(User.class, email))),
|
||||
"Email does not correspond to a valid user");
|
||||
return String.format("Delete user with email %s?", email);
|
||||
}
|
||||
|
||||
@@ -55,11 +56,16 @@ public class DeleteUserCommand extends ConfirmingCommand {
|
||||
protected String execute() throws Exception {
|
||||
tm().transact(
|
||||
() -> {
|
||||
Optional<User> optionalUser = UserDao.loadUser(email);
|
||||
checkArgumentPresent(optionalUser, "Email no longer corresponds to a valid user");
|
||||
tm().delete(optionalUser.get());
|
||||
VKey<User> key = VKey.create(User.class, email);
|
||||
checkArgument(tm().exists(key), "Email no longer corresponds to a valid user");
|
||||
tm().delete(key);
|
||||
});
|
||||
User.revokeIapPermission(email, maybeGroupEmailAddress, cloudTasksUtils, iamClient);
|
||||
User.revokeIapPermission(email, maybeGroupEmailAddress, null, connection, iamClient);
|
||||
return String.format("Deleted user with email %s", email);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConnection(ServiceConnection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,10 +14,12 @@
|
||||
|
||||
package google.registry.tools;
|
||||
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.beust.jcommander.Parameter;
|
||||
import com.beust.jcommander.Parameters;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.model.console.UserDao;
|
||||
import google.registry.persistence.VKey;
|
||||
import java.util.List;
|
||||
|
||||
/** Command to display one or more users. */
|
||||
@@ -29,11 +31,14 @@ public class GetUserCommand implements Command {
|
||||
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
for (String emailAddress : mainParameters) {
|
||||
System.out.println(
|
||||
UserDao.loadUser(emailAddress)
|
||||
.map(User::toString)
|
||||
.orElse(String.format("No user with email address %s", emailAddress)));
|
||||
}
|
||||
tm().transact(
|
||||
() -> {
|
||||
for (String emailAddress : mainParameters) {
|
||||
System.out.println(
|
||||
tm().loadByKeyIfPresent(VKey.create(User.class, emailAddress))
|
||||
.map(User::toString)
|
||||
.orElse(String.format("No user with email address %s", emailAddress)));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,20 +14,20 @@
|
||||
|
||||
package google.registry.tools;
|
||||
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.PreconditionsUtils.checkArgumentPresent;
|
||||
|
||||
import com.beust.jcommander.Parameters;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.model.console.UserDao;
|
||||
import javax.annotation.Nullable;
|
||||
import google.registry.persistence.VKey;
|
||||
|
||||
/** Updates a user, assuming that the user in question already exists. */
|
||||
@Parameters(separators = " =", commandDescription = "Update a user account")
|
||||
public class UpdateUserCommand extends CreateOrUpdateUserCommand {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
User getExistingUser(String email) {
|
||||
return checkArgumentPresent(UserDao.loadUser(email), "User %s not found", email);
|
||||
return checkArgumentPresent(
|
||||
tm().loadByKeyIfPresent(VKey.create(User.class, email)), "User %s not found", email);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ public class ConsoleRegistryLockVerifyAction extends ConsoleApiAction {
|
||||
RegistryLock lock =
|
||||
domainLockUtils.verifyVerificationCode(lockVerificationCode, user.getUserRoles().isAdmin());
|
||||
RegistryLockAction action =
|
||||
lock.getLockCompletionTime().isPresent()
|
||||
lock.getUnlockCompletionTime().isPresent()
|
||||
? RegistryLockAction.UNLOCKED
|
||||
: RegistryLockAction.LOCKED;
|
||||
RegistryLockVerificationResponse lockResponse =
|
||||
|
||||
@@ -17,6 +17,7 @@ package google.registry.ui.server.console.settings;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.request.Action.Method.POST;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_FORBIDDEN;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
|
||||
@@ -30,6 +31,7 @@ import google.registry.request.auth.AuthenticatedRegistrarAccessor;
|
||||
import google.registry.request.auth.AuthenticatedRegistrarAccessor.RegistrarAccessDeniedException;
|
||||
import google.registry.ui.server.console.ConsoleApiAction;
|
||||
import google.registry.ui.server.registrar.ConsoleApiParams;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import javax.inject.Inject;
|
||||
|
||||
@@ -65,10 +67,10 @@ public class WhoisRegistrarFieldsAction extends ConsoleApiAction {
|
||||
checkArgument(registrar.isPresent(), "'registrar' parameter is not present");
|
||||
checkPermission(
|
||||
user, registrar.get().getRegistrarId(), ConsolePermission.EDIT_REGISTRAR_DETAILS);
|
||||
tm().transact(() -> loadAndModifyRegistrar(registrar.get()));
|
||||
tm().transact(() -> loadAndModifyRegistrar(registrar.get(), user));
|
||||
}
|
||||
|
||||
private void loadAndModifyRegistrar(Registrar providedRegistrar) {
|
||||
private void loadAndModifyRegistrar(Registrar providedRegistrar, User user) {
|
||||
Registrar savedRegistrar;
|
||||
try {
|
||||
// reload to make sure the object has all the correct fields
|
||||
@@ -78,6 +80,15 @@ public class WhoisRegistrarFieldsAction extends ConsoleApiAction {
|
||||
return;
|
||||
}
|
||||
|
||||
// icannReferralEmail can't be updated by partners, only by global users with
|
||||
// EDIT_REGISTRAR_DETAILS permission
|
||||
if (!Objects.equals(
|
||||
savedRegistrar.getIcannReferralEmail(), providedRegistrar.getIcannReferralEmail())
|
||||
&& !user.getUserRoles().hasGlobalPermission(ConsolePermission.EDIT_REGISTRAR_DETAILS)) {
|
||||
setFailedResponse(
|
||||
"Icann Referral Email update is not permitted for this user", SC_BAD_REQUEST);
|
||||
}
|
||||
|
||||
Registrar newRegistrar =
|
||||
savedRegistrar
|
||||
.asBuilder()
|
||||
@@ -86,6 +97,8 @@ public class WhoisRegistrarFieldsAction extends ConsoleApiAction {
|
||||
.setLocalizedAddress(providedRegistrar.getLocalizedAddress())
|
||||
.setPhoneNumber(providedRegistrar.getPhoneNumber())
|
||||
.setFaxNumber(providedRegistrar.getFaxNumber())
|
||||
.setIcannReferralEmail(providedRegistrar.getIcannReferralEmail())
|
||||
.setEmailAddress(providedRegistrar.getEmailAddress())
|
||||
.build();
|
||||
tm().put(newRegistrar);
|
||||
sendExternalUpdatesIfNecessary(
|
||||
|
||||
@@ -30,7 +30,6 @@ import google.registry.batch.CloudTasksUtils;
|
||||
import google.registry.config.RegistryConfig.Config;
|
||||
import google.registry.model.console.RegistrarRole;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.model.console.UserDao;
|
||||
import google.registry.model.console.UserRoles;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.model.registrar.RegistrarAddress;
|
||||
@@ -260,10 +259,10 @@ public final class ConsoleRegistrarCreatorAction extends HtmlAction {
|
||||
"Registrar with client ID %s already exists",
|
||||
registrar.getRegistrarId());
|
||||
tm().put(registrar);
|
||||
tm().put(user);
|
||||
});
|
||||
UserDao.saveUser(user);
|
||||
User.grantIapPermission(
|
||||
user.getEmailAddress(), maybeGroupEmailAddress, cloudTasksUtils, iamClient);
|
||||
user.getEmailAddress(), maybeGroupEmailAddress, cloudTasksUtils, null, iamClient);
|
||||
data.put("password", password);
|
||||
data.put("passcode", phonePasscode);
|
||||
|
||||
|
||||
@@ -14,10 +14,13 @@
|
||||
|
||||
package google.registry.ui.server.registrar;
|
||||
|
||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.request.auth.AuthenticatedRegistrarAccessor.Role.ADMIN;
|
||||
import static google.registry.request.auth.AuthenticatedRegistrarAccessor.Role.OWNER;
|
||||
import static google.registry.ui.server.SoyTemplateUtils.CSS_RENAMING_MAP_SUPPLIER;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_FORBIDDEN;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_PERMANENT_REDIRECT;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
@@ -26,6 +29,8 @@ import com.google.common.flogger.FluentLogger;
|
||||
import com.google.template.soy.data.SoyMapData;
|
||||
import com.google.template.soy.tofu.SoyTofu;
|
||||
import google.registry.config.RegistryConfig.Config;
|
||||
import google.registry.model.common.FeatureFlag;
|
||||
import google.registry.model.console.GlobalRole;
|
||||
import google.registry.request.Action;
|
||||
import google.registry.request.Parameter;
|
||||
import google.registry.request.auth.Auth;
|
||||
@@ -35,8 +40,10 @@ import google.registry.request.auth.AuthenticatedRegistrarAccessor.Role;
|
||||
import google.registry.ui.server.SoyTemplateUtils;
|
||||
import google.registry.ui.soy.registrar.ConsoleSoyInfo;
|
||||
import google.registry.util.RegistryEnvironment;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/** Action that serves Registrar Console single HTML page (SPA). */
|
||||
@@ -100,6 +107,7 @@ public final class ConsoleUiAction extends HtmlAction {
|
||||
soyMapData.put("announcementsEmail", announcementsEmail);
|
||||
soyMapData.put("supportPhoneNumber", supportPhoneNumber);
|
||||
soyMapData.put("technicalDocsUrl", technicalDocsUrl);
|
||||
|
||||
if (!enabled) {
|
||||
response.setStatus(SC_SERVICE_UNAVAILABLE);
|
||||
response.setPayload(
|
||||
@@ -111,9 +119,35 @@ public final class ConsoleUiAction extends HtmlAction {
|
||||
.render());
|
||||
return;
|
||||
}
|
||||
|
||||
// Set permanent redirect to the new console for tech support
|
||||
if (isNullOrEmpty(req.getParameter("redirect"))
|
||||
&& Stream.of(GlobalRole.SUPPORT_LEAD, GlobalRole.SUPPORT_AGENT)
|
||||
.anyMatch(
|
||||
globalRole ->
|
||||
globalRole.equals(authResult.user().get().getUserRoles().getGlobalRole()))) {
|
||||
response.setStatus(SC_PERMANENT_REDIRECT);
|
||||
try {
|
||||
response.sendRedirect("/console");
|
||||
return;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
ImmutableSetMultimap<String, Role> roleMap = registrarAccessor.getAllRegistrarIdsWithRoles();
|
||||
soyMapData.put("allClientIds", roleMap.keySet());
|
||||
soyMapData.put("environment", RegistryEnvironment.get().toString());
|
||||
boolean newConsole =
|
||||
tm().transact(
|
||||
() ->
|
||||
FeatureFlag.getUncached(FeatureFlag.FeatureName.NEW_CONSOLE)
|
||||
.map(
|
||||
flag ->
|
||||
flag.getStatus(tm().getTransactionTime())
|
||||
.equals(FeatureFlag.FeatureStatus.ACTIVE))
|
||||
.orElse(false));
|
||||
soyMapData.put("includeDeprecationWarning", newConsole);
|
||||
// We set the initial value to the value that will show if guessClientId throws.
|
||||
String clientId = "<null>";
|
||||
try {
|
||||
|
||||
@@ -261,7 +261,7 @@ li.kd-menulistitem {
|
||||
top: 136px;
|
||||
left: 173px;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
width: calc(100% - 173px);
|
||||
margin: 0;
|
||||
padding: 25px 0 1em 0;
|
||||
overflow-y: scroll !important;
|
||||
@@ -296,3 +296,31 @@ li.kd-menulistitem {
|
||||
.reg-select {
|
||||
margin-left: 23px;
|
||||
}
|
||||
|
||||
div#reg-deprecation-warning {
|
||||
position: fixed;
|
||||
top: 64px;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
text-align: center;
|
||||
background-color: #ba2a1a;
|
||||
font-size: 0.6svw;
|
||||
}
|
||||
|
||||
div#reg-deprecation-warning h1 {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
div#reg-deprecation-warning a {
|
||||
color: #add8e6;
|
||||
}
|
||||
|
||||
div#reg-accessing-as-role {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1600px) {
|
||||
div#reg-deprecation-warning {
|
||||
font-size: 0.85vw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
{@param technicalDocsUrl: string}
|
||||
{@param environment: string}
|
||||
{@param analyticsConfig: [googleAnalyticsId: string|null]}
|
||||
{@param includeDeprecationWarning: bool}
|
||||
|
||||
{call registry.soy.console.header}
|
||||
{param app: 'registrar' /}
|
||||
@@ -45,7 +46,7 @@
|
||||
{call registry.soy.console.googlebar data="all" /}
|
||||
<div id="reg-app" lang="en-US">
|
||||
<div id="reg-appbar" class="{css('kd-appbar')}">
|
||||
<div class="{css('kd-description')}">
|
||||
<div id="reg-accessing-as-role" class="{css('kd-description')}">
|
||||
Accessing <span class="{css('kd-value')}">{$clientId}</span> as{sp}
|
||||
{if $isOwner}<span class="{css('kd-value')}">Owner</span>{/if}
|
||||
{if $isAdmin}<span class="{css('kd-value')}">Admin</span>{/if}
|
||||
@@ -53,6 +54,13 @@
|
||||
{sp}(Switch registrar: {call .clientIdSelect_ data="all" /})
|
||||
{/if}
|
||||
</div>
|
||||
{if $includeDeprecationWarning}
|
||||
<div id="reg-deprecation-warning">
|
||||
<h1>Note: this console is deprecated and will be deactivated in October 2024.
|
||||
Please use the <a href="/console">new console</a> instead.
|
||||
</h1>
|
||||
</div>
|
||||
{/if}
|
||||
<div id="reg-app-buttons" class="{css('kd-buttonbar')} {css('left')}"></div>
|
||||
</div>
|
||||
{call .navbar_ data="all" /}
|
||||
|
||||
@@ -344,8 +344,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
.and()
|
||||
.hasPeriodYears(2);
|
||||
RenewalPriceInfo renewalPriceInfo =
|
||||
DomainCreateFlow.getRenewalPriceInfo(
|
||||
isAnchorTenant, Optional.ofNullable(allocationToken), feesAndCredits);
|
||||
DomainCreateFlow.getRenewalPriceInfo(isAnchorTenant, Optional.ofNullable(allocationToken));
|
||||
// There should be one bill for the create and one for the recurrence autorenew event.
|
||||
BillingEvent createBillingEvent =
|
||||
new BillingEvent.Builder()
|
||||
@@ -3189,53 +3188,25 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
|
||||
@Test
|
||||
void testGetRenewalPriceInfo_isAnchorTenantWithoutToken_returnsNonPremiumAndNullPrice() {
|
||||
assertThat(
|
||||
DomainCreateFlow.getRenewalPriceInfo(
|
||||
true,
|
||||
Optional.empty(),
|
||||
new FeesAndCredits.Builder()
|
||||
.setCurrency(USD)
|
||||
.addFeeOrCredit(Fee.create(BigDecimal.valueOf(0), FeeType.CREATE, false))
|
||||
.build()))
|
||||
assertThat(DomainCreateFlow.getRenewalPriceInfo(true, Optional.empty()))
|
||||
.isEqualTo(RenewalPriceInfo.create(NONPREMIUM, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetRenewalPriceInfo_isAnchorTenantWithDefaultToken_returnsNonPremiumAndNullPrice() {
|
||||
assertThat(
|
||||
DomainCreateFlow.getRenewalPriceInfo(
|
||||
true,
|
||||
Optional.of(allocationToken),
|
||||
new FeesAndCredits.Builder()
|
||||
.setCurrency(USD)
|
||||
.addFeeOrCredit(Fee.create(BigDecimal.valueOf(0), FeeType.CREATE, false))
|
||||
.build()))
|
||||
assertThat(DomainCreateFlow.getRenewalPriceInfo(true, Optional.of(allocationToken)))
|
||||
.isEqualTo(RenewalPriceInfo.create(NONPREMIUM, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetRenewalPriceInfo_isNotAnchorTenantWithDefaultToken_returnsDefaultAndNullPrice() {
|
||||
assertThat(
|
||||
DomainCreateFlow.getRenewalPriceInfo(
|
||||
false,
|
||||
Optional.of(allocationToken),
|
||||
new FeesAndCredits.Builder()
|
||||
.setCurrency(USD)
|
||||
.addFeeOrCredit(Fee.create(BigDecimal.valueOf(100), FeeType.CREATE, false))
|
||||
.build()))
|
||||
assertThat(DomainCreateFlow.getRenewalPriceInfo(false, Optional.of(allocationToken)))
|
||||
.isEqualTo(RenewalPriceInfo.create(DEFAULT, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetRenewalPriceInfo_isNotAnchorTenantWithoutToken_returnsDefaultAndNullPrice() {
|
||||
assertThat(
|
||||
DomainCreateFlow.getRenewalPriceInfo(
|
||||
false,
|
||||
Optional.empty(),
|
||||
new FeesAndCredits.Builder()
|
||||
.setCurrency(USD)
|
||||
.addFeeOrCredit(Fee.create(BigDecimal.valueOf(100), FeeType.CREATE, false))
|
||||
.build()))
|
||||
assertThat(DomainCreateFlow.getRenewalPriceInfo(false, Optional.empty()))
|
||||
.isEqualTo(RenewalPriceInfo.create(DEFAULT, null));
|
||||
}
|
||||
|
||||
@@ -3248,17 +3219,10 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
.setToken("abc123")
|
||||
.setTokenType(SINGLE_USE)
|
||||
.setRenewalPriceBehavior(SPECIFIED)
|
||||
.setRenewalPrice(Money.of(USD, 0))
|
||||
.setRenewalPrice(Money.of(USD, 5))
|
||||
.build());
|
||||
assertThat(
|
||||
DomainCreateFlow.getRenewalPriceInfo(
|
||||
false,
|
||||
Optional.of(token),
|
||||
new FeesAndCredits.Builder()
|
||||
.setCurrency(USD)
|
||||
.addFeeOrCredit(Fee.create(BigDecimal.valueOf(100), FeeType.CREATE, false))
|
||||
.build()))
|
||||
.isEqualTo(RenewalPriceInfo.create(SPECIFIED, Money.of(USD, 100)));
|
||||
assertThat(DomainCreateFlow.getRenewalPriceInfo(false, Optional.of(token)))
|
||||
.isEqualTo(RenewalPriceInfo.create(SPECIFIED, Money.of(USD, 5)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -3276,11 +3240,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
.setTokenType(SINGLE_USE)
|
||||
.setRenewalPriceBehavior(SPECIFIED)
|
||||
.setRenewalPrice(Money.of(USD, 0))
|
||||
.build())),
|
||||
new FeesAndCredits.Builder()
|
||||
.setCurrency(USD)
|
||||
.addFeeOrCredit(Fee.create(BigDecimal.valueOf(0), FeeType.CREATE, true))
|
||||
.build()));
|
||||
.build()))));
|
||||
assertThat(thrown)
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Renewal price behavior cannot be SPECIFIED for anchor tenant");
|
||||
@@ -3300,11 +3260,7 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
.setToken("abc123")
|
||||
.setTokenType(SINGLE_USE)
|
||||
.setRenewalPriceBehavior(RenewalPriceBehavior.valueOf("INVALID"))
|
||||
.build())),
|
||||
new FeesAndCredits.Builder()
|
||||
.setCurrency(USD)
|
||||
.addFeeOrCredit(Fee.create(BigDecimal.valueOf(0), FeeType.CREATE, true))
|
||||
.build()));
|
||||
.build()))));
|
||||
assertThat(thrown)
|
||||
.hasMessageThat()
|
||||
.isEqualTo(
|
||||
|
||||
@@ -104,8 +104,10 @@ import google.registry.model.contact.Contact;
|
||||
import google.registry.model.domain.DesignatedContact;
|
||||
import google.registry.model.domain.DesignatedContact.Type;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.domain.DomainAuthInfo;
|
||||
import google.registry.model.domain.DomainHistory;
|
||||
import google.registry.model.domain.secdns.DomainDsData;
|
||||
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
|
||||
import google.registry.model.eppcommon.Trid;
|
||||
import google.registry.model.host.Host;
|
||||
import google.registry.model.poll.PendingActionNotificationResponse.DomainPendingActionNotificationResponse;
|
||||
@@ -264,6 +266,38 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
|
||||
doSuccessfulTest("generic_success_response_no_cltrid.xml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_noExistingAuthData() throws Exception {
|
||||
setEppInput("domain_update_no_auth_change.xml");
|
||||
persistReferencedEntities();
|
||||
persistDomain();
|
||||
persistResource(
|
||||
reloadResourceByForeignKey()
|
||||
.asBuilder()
|
||||
.setAuthInfo(DomainAuthInfo.create(PasswordAuth.create(null)))
|
||||
.build());
|
||||
assertMutatingFlow(true);
|
||||
runFlowAssertResponse(loadFile("generic_success_response.xml"));
|
||||
Domain domain = reloadResourceByForeignKey();
|
||||
// Check that the domain was updated. These values came from the xml.
|
||||
assertAboutDomains()
|
||||
.that(domain)
|
||||
.hasStatusValue(CLIENT_HOLD)
|
||||
.and()
|
||||
.hasAuthInfoPwd(null)
|
||||
.and()
|
||||
.hasOneHistoryEntryEachOfTypes(DOMAIN_CREATE, DOMAIN_UPDATE)
|
||||
.and()
|
||||
.hasLastEppUpdateTime(clock.nowUtc())
|
||||
.and()
|
||||
.hasLastEppUpdateRegistrarId("TheRegistrar")
|
||||
.and()
|
||||
.hasNoAutorenewEndTime();
|
||||
assertNoBillingEvents();
|
||||
assertDomainDnsRequests("example.tld");
|
||||
assertLastHistoryContainsResource(reloadResourceByForeignKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_cachingDisabled() throws Exception {
|
||||
boolean origIsCachingEnabled = RegistryConfig.isEppResourceCachingEnabled();
|
||||
|
||||
@@ -22,6 +22,7 @@ import static google.registry.persistence.transaction.JpaTransactionManagerExten
|
||||
import static google.registry.testing.CertificateSamples.SAMPLE_CERT;
|
||||
import static google.registry.testing.CertificateSamples.SAMPLE_CERT_HASH;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.loadByKeyIfPresent;
|
||||
import static google.registry.testing.DatabaseHelper.persistPremiumList;
|
||||
import static google.registry.testing.DatabaseHelper.persistSimpleResource;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
@@ -36,10 +37,10 @@ import com.google.common.collect.ImmutableList;
|
||||
import google.registry.batch.CloudTasksUtils;
|
||||
import google.registry.model.console.RegistrarRole;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.model.console.UserDao;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.model.tld.Tld;
|
||||
import google.registry.model.tld.Tld.TldState;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
|
||||
import google.registry.testing.CloudTasksHelper;
|
||||
@@ -106,7 +107,7 @@ public final class OteAccountBuilderTest {
|
||||
}
|
||||
|
||||
public static void verifyUser(String registrarId, String email) {
|
||||
Optional<User> maybeUser = UserDao.loadUser(email);
|
||||
Optional<User> maybeUser = loadByKeyIfPresent(VKey.create(User.class, email));
|
||||
assertThat(maybeUser).isPresent();
|
||||
assertThat(maybeUser.get().getUserRoles().getRegistrarRoles().get(registrarId))
|
||||
.isEqualTo(RegistrarRole.ACCOUNT_MANAGER);
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
// Copyright 2022 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.model.console;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import google.registry.model.EntityTestCase;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Tests for {@link UserDao}. */
|
||||
public class UserDaoTest extends EntityTestCase {
|
||||
|
||||
@Test
|
||||
void testSuccess_saveAndRetrieve() {
|
||||
User user1 =
|
||||
new User.Builder()
|
||||
.setEmailAddress("email@email.com")
|
||||
.setUserRoles(new UserRoles.Builder().setGlobalRole(GlobalRole.SUPPORT_AGENT).build())
|
||||
.build();
|
||||
User user2 =
|
||||
new User.Builder()
|
||||
.setEmailAddress("foo@bar.com")
|
||||
.setUserRoles(new UserRoles.Builder().setGlobalRole(GlobalRole.SUPPORT_AGENT).build())
|
||||
.build();
|
||||
UserDao.saveUser(user1);
|
||||
UserDao.saveUser(user2);
|
||||
assertAboutImmutableObjects()
|
||||
.that(user1)
|
||||
.isEqualExceptFields(UserDao.loadUser("email@email.com").get(), "id", "updateTimestamp");
|
||||
assertAboutImmutableObjects()
|
||||
.that(user2)
|
||||
.isEqualExceptFields(UserDao.loadUser("foo@bar.com").get(), "id", "updateTimestamp");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_absentUser() {
|
||||
User user =
|
||||
new User.Builder()
|
||||
.setEmailAddress("email@email.com")
|
||||
.setUserRoles(new UserRoles.Builder().setGlobalRole(GlobalRole.SUPPORT_AGENT).build())
|
||||
.build();
|
||||
UserDao.saveUser(user);
|
||||
User fromDb = UserDao.loadUser("email@email.com").get();
|
||||
// nonexistent one should never exist
|
||||
assertThat(UserDao.loadUser("nonexistent@email.com")).isEmpty();
|
||||
// now try deleting the one that does exist
|
||||
tm().transact(() -> tm().delete(fromDb));
|
||||
assertThat(UserDao.loadUser("email@email.com")).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_updateUser_sameEmail() {
|
||||
User user1 =
|
||||
new User.Builder()
|
||||
.setEmailAddress("email@email.com")
|
||||
.setUserRoles(new UserRoles.Builder().setGlobalRole(GlobalRole.SUPPORT_AGENT).build())
|
||||
.build();
|
||||
User user2 =
|
||||
new User.Builder()
|
||||
.setEmailAddress("email@email.com")
|
||||
.setUserRoles(new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).build())
|
||||
.build();
|
||||
UserDao.saveUser(user1);
|
||||
UserDao.saveUser(user2);
|
||||
assertAboutImmutableObjects()
|
||||
.that(user2)
|
||||
.isEqualExceptFields(UserDao.loadUser("email@email.com").get(), "updateTimestamp");
|
||||
}
|
||||
}
|
||||
@@ -21,15 +21,20 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
import com.google.cloud.tasks.v2.HttpMethod;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.net.MediaType;
|
||||
import google.registry.batch.CloudTasksUtils;
|
||||
import google.registry.model.EntityTestCase;
|
||||
import google.registry.testing.CloudTasksHelper;
|
||||
import google.registry.testing.CloudTasksHelper.TaskMatcher;
|
||||
import google.registry.testing.DatabaseHelper;
|
||||
import google.registry.tools.IamClient;
|
||||
import google.registry.tools.ServiceConnection;
|
||||
import google.registry.tools.server.UpdateUserGroupAction;
|
||||
import java.util.Optional;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -57,6 +62,34 @@ public class UserTest extends EntityTestCase {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_asyncAndSyncModeConflict() {
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> User.grantIapPermission("email@example.com", Optional.empty(), null, null, null));
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() ->
|
||||
User.grantIapPermission(
|
||||
"email@example.com",
|
||||
Optional.empty(),
|
||||
mock(CloudTasksUtils.class),
|
||||
mock(ServiceConnection.class),
|
||||
null));
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> User.revokeIapPermission("email@example.com", Optional.empty(), null, null, null));
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() ->
|
||||
User.revokeIapPermission(
|
||||
"email@example.com",
|
||||
Optional.empty(),
|
||||
mock(CloudTasksUtils.class),
|
||||
mock(ServiceConnection.class),
|
||||
null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_badInputs() {
|
||||
User.Builder builder = new User.Builder();
|
||||
@@ -116,19 +149,20 @@ public class UserTest extends EntityTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGrantIapPermission() {
|
||||
void testGrantIapPermissionAsync() {
|
||||
CloudTasksHelper cloudTasksHelper = new CloudTasksHelper();
|
||||
IamClient iamClient = mock(IamClient.class);
|
||||
CloudTasksUtils cloudTasksUtils = cloudTasksHelper.getTestCloudTasksUtils();
|
||||
|
||||
// Individual permission.
|
||||
User.grantIapPermission("email@example.com", Optional.empty(), cloudTasksUtils, iamClient);
|
||||
User.grantIapPermission(
|
||||
"email@example.com", Optional.empty(), cloudTasksUtils, null, iamClient);
|
||||
cloudTasksHelper.assertNoTasksEnqueued();
|
||||
verify(iamClient).addBinding("email@example.com", IAP_SECURED_WEB_APP_USER_ROLE);
|
||||
|
||||
// Group membership.
|
||||
User.grantIapPermission(
|
||||
"email@example.com", Optional.of("console@example.com"), cloudTasksUtils, iamClient);
|
||||
"email@example.com", Optional.of("console@example.com"), cloudTasksUtils, null, iamClient);
|
||||
cloudTasksHelper.assertTasksEnqueued(
|
||||
"console-user-group-update",
|
||||
new TaskMatcher()
|
||||
@@ -142,19 +176,49 @@ public class UserTest extends EntityTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRevokeIapPermission() {
|
||||
void testGrantIapPermissionSync() throws Exception {
|
||||
ServiceConnection connection = mock(ServiceConnection.class);
|
||||
IamClient iamClient = mock(IamClient.class);
|
||||
|
||||
// Individual permission.
|
||||
User.grantIapPermission("email@example.com", Optional.empty(), null, connection, iamClient);
|
||||
verifyNoInteractions(connection);
|
||||
verify(iamClient).addBinding("email@example.com", IAP_SECURED_WEB_APP_USER_ROLE);
|
||||
|
||||
// Group membership.
|
||||
User.grantIapPermission(
|
||||
"email@example.com", Optional.of("console@example.com"), null, connection, iamClient);
|
||||
verify(connection)
|
||||
.sendPostRequest(
|
||||
UpdateUserGroupAction.PATH,
|
||||
ImmutableMap.of(
|
||||
"userEmailAddress",
|
||||
"email@example.com",
|
||||
"groupEmailAddress",
|
||||
"console@example.com",
|
||||
"groupUpdateMode",
|
||||
"ADD"),
|
||||
MediaType.PLAIN_TEXT_UTF_8,
|
||||
new byte[0]);
|
||||
verifyNoMoreInteractions(iamClient);
|
||||
verifyNoMoreInteractions(connection);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRevokeIapPermissionAsync() {
|
||||
CloudTasksHelper cloudTasksHelper = new CloudTasksHelper();
|
||||
IamClient iamClient = mock(IamClient.class);
|
||||
CloudTasksUtils cloudTasksUtils = cloudTasksHelper.getTestCloudTasksUtils();
|
||||
|
||||
// Individual permission.
|
||||
User.revokeIapPermission("email@example.com", Optional.empty(), cloudTasksUtils, iamClient);
|
||||
User.revokeIapPermission(
|
||||
"email@example.com", Optional.empty(), cloudTasksUtils, null, iamClient);
|
||||
cloudTasksHelper.assertNoTasksEnqueued();
|
||||
verify(iamClient).removeBinding("email@example.com", IAP_SECURED_WEB_APP_USER_ROLE);
|
||||
|
||||
// Group membership.
|
||||
User.revokeIapPermission(
|
||||
"email@example.com", Optional.of("console@example.com"), cloudTasksUtils, iamClient);
|
||||
"email@example.com", Optional.of("console@example.com"), cloudTasksUtils, null, iamClient);
|
||||
cloudTasksHelper.assertTasksEnqueued(
|
||||
"console-user-group-update",
|
||||
new TaskMatcher()
|
||||
@@ -166,4 +230,33 @@ public class UserTest extends EntityTestCase {
|
||||
.param("groupUpdateMode", "REMOVE"));
|
||||
verifyNoMoreInteractions(iamClient);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRevokeIapPermissionSync() throws Exception {
|
||||
ServiceConnection connection = mock(ServiceConnection.class);
|
||||
IamClient iamClient = mock(IamClient.class);
|
||||
|
||||
// Individual permission.
|
||||
User.revokeIapPermission("email@example.com", Optional.empty(), null, connection, iamClient);
|
||||
verifyNoInteractions(connection);
|
||||
verify(iamClient).removeBinding("email@example.com", IAP_SECURED_WEB_APP_USER_ROLE);
|
||||
|
||||
// Group membership.
|
||||
User.revokeIapPermission(
|
||||
"email@example.com", Optional.of("console@example.com"), null, connection, iamClient);
|
||||
verify(connection)
|
||||
.sendPostRequest(
|
||||
UpdateUserGroupAction.PATH,
|
||||
ImmutableMap.of(
|
||||
"userEmailAddress",
|
||||
"email@example.com",
|
||||
"groupEmailAddress",
|
||||
"console@example.com",
|
||||
"groupUpdateMode",
|
||||
"REMOVE"),
|
||||
MediaType.PLAIN_TEXT_UTF_8,
|
||||
new byte[0]);
|
||||
verifyNoMoreInteractions(iamClient);
|
||||
verifyNoMoreInteractions(connection);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,6 @@ import google.registry.model.billing.BillingRecurrence;
|
||||
import google.registry.model.common.DnsRefreshRequest;
|
||||
import google.registry.model.console.GlobalRole;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.model.console.UserDao;
|
||||
import google.registry.model.console.UserRoles;
|
||||
import google.registry.model.contact.Contact;
|
||||
import google.registry.model.contact.ContactAuthInfo;
|
||||
@@ -1014,20 +1013,33 @@ public final class DatabaseHelper {
|
||||
return tm().transact(() -> tm().loadByEntity(resource));
|
||||
}
|
||||
|
||||
public static User loadExistingUser(String emailAddress) {
|
||||
return loadByKey(VKey.create(User.class, emailAddress));
|
||||
}
|
||||
|
||||
/** Persists an admin {@link User} with the given email address if it doesn't already exist. */
|
||||
public static User createAdminUser(String emailAddress) {
|
||||
Optional<User> existingUser = UserDao.loadUser(emailAddress);
|
||||
if (existingUser.isPresent()) {
|
||||
return existingUser.get();
|
||||
}
|
||||
User user =
|
||||
new User.Builder()
|
||||
.setEmailAddress(emailAddress)
|
||||
.setUserRoles(
|
||||
new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).setIsAdmin(true).build())
|
||||
.build();
|
||||
tm().transact(() -> tm().put(user));
|
||||
return UserDao.loadUser(emailAddress).get();
|
||||
// Reload the user to pick up the update time
|
||||
return loadByEntity(
|
||||
tm().transact(
|
||||
() -> {
|
||||
VKey<User> key = VKey.create(User.class, emailAddress);
|
||||
Optional<User> existingUser = tm().loadByKeyIfPresent(key);
|
||||
if (existingUser.isPresent()) {
|
||||
return existingUser.get();
|
||||
}
|
||||
User user =
|
||||
new User.Builder()
|
||||
.setEmailAddress(emailAddress)
|
||||
.setUserRoles(
|
||||
new UserRoles.Builder()
|
||||
.setGlobalRole(GlobalRole.FTE)
|
||||
.setIsAdmin(true)
|
||||
.build())
|
||||
.build();
|
||||
tm().put(user);
|
||||
return user;
|
||||
}));
|
||||
}
|
||||
|
||||
/** Returns all the history entries that are parented off the given EppResource. */
|
||||
|
||||
@@ -29,6 +29,7 @@ import google.registry.model.eppcommon.AuthInfo;
|
||||
import google.registry.testing.TruthChainer.And;
|
||||
import google.registry.tmch.LordnTaskUtils.LordnPhase;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/** Truth subject for asserting things about {@link Domain} instances. */
|
||||
@@ -65,7 +66,7 @@ public final class DomainSubject extends AbstractEppResourceSubject<Domain, Doma
|
||||
return hasValue(lordnPhase, actual.getLordnPhase(), "lordnPhase");
|
||||
}
|
||||
|
||||
public And<DomainSubject> hasAuthInfoPwd(String pw) {
|
||||
public And<DomainSubject> hasAuthInfoPwd(@Nullable String pw) {
|
||||
AuthInfo authInfo = actual.getAuthInfo();
|
||||
return hasValue(pw, authInfo == null ? null : authInfo.getPw().getValue(), "has auth info pw");
|
||||
}
|
||||
|
||||
@@ -16,22 +16,21 @@ package google.registry.tools;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.console.User.IAP_SECURED_WEB_APP_USER_ROLE;
|
||||
import static google.registry.testing.DatabaseHelper.loadExistingUser;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
import com.google.cloud.tasks.v2.HttpMethod;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.net.MediaType;
|
||||
import google.registry.model.console.GlobalRole;
|
||||
import google.registry.model.console.RegistrarRole;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.model.console.UserDao;
|
||||
import google.registry.testing.CloudTasksHelper;
|
||||
import google.registry.testing.CloudTasksHelper.TaskMatcher;
|
||||
import google.registry.testing.DatabaseHelper;
|
||||
import google.registry.tools.server.UpdateUserGroupAction;
|
||||
import java.util.Optional;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -40,13 +39,13 @@ import org.junit.jupiter.api.Test;
|
||||
public class CreateUserCommandTest extends CommandTestCase<CreateUserCommand> {
|
||||
|
||||
private final IamClient iamClient = mock(IamClient.class);
|
||||
private final CloudTasksHelper cloudTasksHelper = new CloudTasksHelper();
|
||||
private final ServiceConnection connection = mock(ServiceConnection.class);
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
command.iamClient = iamClient;
|
||||
command.maybeGroupEmailAddress = Optional.empty();
|
||||
command.cloudTasksUtils = cloudTasksHelper.getTestCloudTasksUtils();
|
||||
command.setConnection(connection);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -59,7 +58,7 @@ public class CreateUserCommandTest extends CommandTestCase<CreateUserCommand> {
|
||||
assertThat(onlyUser.getUserRoles().getRegistrarRoles()).isEmpty();
|
||||
verify(iamClient).addBinding("user@example.test", IAP_SECURED_WEB_APP_USER_ROLE);
|
||||
verifyNoMoreInteractions(iamClient);
|
||||
cloudTasksHelper.assertNoTasksEnqueued("console-user-group-update");
|
||||
verifyNoInteractions(connection);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -71,16 +70,20 @@ public class CreateUserCommandTest extends CommandTestCase<CreateUserCommand> {
|
||||
assertThat(onlyUser.getUserRoles().isAdmin()).isFalse();
|
||||
assertThat(onlyUser.getUserRoles().getGlobalRole()).isEqualTo(GlobalRole.NONE);
|
||||
assertThat(onlyUser.getUserRoles().getRegistrarRoles()).isEmpty();
|
||||
cloudTasksHelper.assertTasksEnqueued(
|
||||
"console-user-group-update",
|
||||
new TaskMatcher()
|
||||
.method(HttpMethod.POST)
|
||||
.service("TOOLS")
|
||||
.path("/_dr/admin/updateUserGroup")
|
||||
.param("userEmailAddress", "user@example.test")
|
||||
.param("groupEmailAddress", "group@example.test")
|
||||
.param("groupUpdateMode", "ADD"));
|
||||
verify(connection)
|
||||
.sendPostRequest(
|
||||
UpdateUserGroupAction.PATH,
|
||||
ImmutableMap.of(
|
||||
"userEmailAddress",
|
||||
"user@example.test",
|
||||
"groupEmailAddress",
|
||||
"group@example.test",
|
||||
"groupUpdateMode",
|
||||
"ADD"),
|
||||
MediaType.PLAIN_TEXT_UTF_8,
|
||||
new byte[0]);
|
||||
verifyNoInteractions(iamClient);
|
||||
verifyNoMoreInteractions(connection);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -90,27 +93,27 @@ public class CreateUserCommandTest extends CommandTestCase<CreateUserCommand> {
|
||||
"user@example.test",
|
||||
"--registry_lock_email_address",
|
||||
"registrylockemail@otherexample.test");
|
||||
assertThat(UserDao.loadUser("user@example.test").get().getRegistryLockEmailAddress())
|
||||
assertThat(loadExistingUser("user@example.test").getRegistryLockEmailAddress())
|
||||
.hasValue("registrylockemail@otherexample.test");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_admin() throws Exception {
|
||||
runCommandForced("--email", "user@example.test", "--admin", "true");
|
||||
assertThat(UserDao.loadUser("user@example.test").get().getUserRoles().isAdmin()).isTrue();
|
||||
assertThat(loadExistingUser("user@example.test").getUserRoles().isAdmin()).isTrue();
|
||||
verify(iamClient).addBinding("user@example.test", IAP_SECURED_WEB_APP_USER_ROLE);
|
||||
verifyNoMoreInteractions(iamClient);
|
||||
cloudTasksHelper.assertNoTasksEnqueued("console-user-group-update");
|
||||
verifyNoInteractions(connection);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_globalRole() throws Exception {
|
||||
runCommandForced("--email", "user@example.test", "--global_role", "FTE");
|
||||
assertThat(UserDao.loadUser("user@example.test").get().getUserRoles().getGlobalRole())
|
||||
assertThat(loadExistingUser("user@example.test").getUserRoles().getGlobalRole())
|
||||
.isEqualTo(GlobalRole.FTE);
|
||||
verify(iamClient).addBinding("user@example.test", IAP_SECURED_WEB_APP_USER_ROLE);
|
||||
verifyNoMoreInteractions(iamClient);
|
||||
cloudTasksHelper.assertNoTasksEnqueued("console-user-group-update");
|
||||
verifyNoInteractions(connection);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -120,7 +123,7 @@ public class CreateUserCommandTest extends CommandTestCase<CreateUserCommand> {
|
||||
"user@example.test",
|
||||
"--registrar_roles",
|
||||
"TheRegistrar=ACCOUNT_MANAGER,NewRegistrar=PRIMARY_CONTACT");
|
||||
assertThat(UserDao.loadUser("user@example.test").get().getUserRoles().getRegistrarRoles())
|
||||
assertThat(loadExistingUser("user@example.test").getUserRoles().getRegistrarRoles())
|
||||
.isEqualTo(
|
||||
ImmutableMap.of(
|
||||
"TheRegistrar",
|
||||
@@ -129,7 +132,7 @@ public class CreateUserCommandTest extends CommandTestCase<CreateUserCommand> {
|
||||
RegistrarRole.PRIMARY_CONTACT));
|
||||
verify(iamClient).addBinding("user@example.test", IAP_SECURED_WEB_APP_USER_ROLE);
|
||||
verifyNoMoreInteractions(iamClient);
|
||||
cloudTasksHelper.assertNoTasksEnqueued("console-user-group-update");
|
||||
verifyNoInteractions(connection);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -144,7 +147,7 @@ public class CreateUserCommandTest extends CommandTestCase<CreateUserCommand> {
|
||||
.hasMessageThat()
|
||||
.isEqualTo("A user with email user@example.test already exists");
|
||||
verifyNoMoreInteractions(iamClient);
|
||||
cloudTasksHelper.assertNoTasksEnqueued("console-user-group-update");
|
||||
verifyNoInteractions(connection);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -22,11 +22,12 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
import com.google.cloud.tasks.v2.HttpMethod;
|
||||
import google.registry.model.console.UserDao;
|
||||
import google.registry.testing.CloudTasksHelper;
|
||||
import google.registry.testing.CloudTasksHelper.TaskMatcher;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.net.MediaType;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.testing.DatabaseHelper;
|
||||
import google.registry.tools.server.UpdateUserGroupAction;
|
||||
import java.util.Optional;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -35,43 +36,49 @@ import org.junit.jupiter.api.Test;
|
||||
public class DeleteUserCommandTest extends CommandTestCase<DeleteUserCommand> {
|
||||
|
||||
private final IamClient iamClient = mock(IamClient.class);
|
||||
private final CloudTasksHelper cloudTasksHelper = new CloudTasksHelper();
|
||||
private final ServiceConnection connection = mock(ServiceConnection.class);
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
command.iamClient = iamClient;
|
||||
command.maybeGroupEmailAddress = Optional.empty();
|
||||
command.cloudTasksUtils = cloudTasksHelper.getTestCloudTasksUtils();
|
||||
command.setConnection(connection);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_deletesUser() throws Exception {
|
||||
DatabaseHelper.createAdminUser("email@example.test");
|
||||
assertThat(UserDao.loadUser("email@example.test")).isPresent();
|
||||
VKey<User> key = VKey.create(User.class, "email@example.test");
|
||||
assertThat(DatabaseHelper.loadByKeyIfPresent(key)).isPresent();
|
||||
runCommandForced("--email", "email@example.test");
|
||||
assertThat(UserDao.loadUser("email@example.test")).isEmpty();
|
||||
assertThat(DatabaseHelper.loadByKeyIfPresent(key)).isEmpty();
|
||||
verify(iamClient).removeBinding("email@example.test", IAP_SECURED_WEB_APP_USER_ROLE);
|
||||
verifyNoMoreInteractions(iamClient);
|
||||
cloudTasksHelper.assertNoTasksEnqueued("console-user-group-update");
|
||||
verifyNoInteractions(connection);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_deletesUser_removeFromGroup() throws Exception {
|
||||
command.maybeGroupEmailAddress = Optional.of("group@example.test");
|
||||
DatabaseHelper.createAdminUser("email@example.test");
|
||||
assertThat(UserDao.loadUser("email@example.test")).isPresent();
|
||||
VKey<User> key = VKey.create(User.class, "email@example.test");
|
||||
assertThat(DatabaseHelper.loadByKeyIfPresent(key)).isPresent();
|
||||
runCommandForced("--email", "email@example.test");
|
||||
assertThat(UserDao.loadUser("email@example.test")).isEmpty();
|
||||
cloudTasksHelper.assertTasksEnqueued(
|
||||
"console-user-group-update",
|
||||
new TaskMatcher()
|
||||
.method(HttpMethod.POST)
|
||||
.service("TOOLS")
|
||||
.path("/_dr/admin/updateUserGroup")
|
||||
.param("userEmailAddress", "email@example.test")
|
||||
.param("groupEmailAddress", "group@example.test")
|
||||
.param("groupUpdateMode", "REMOVE"));
|
||||
assertThat(DatabaseHelper.loadByKeyIfPresent(key)).isEmpty();
|
||||
verify(connection)
|
||||
.sendPostRequest(
|
||||
UpdateUserGroupAction.PATH,
|
||||
ImmutableMap.of(
|
||||
"userEmailAddress",
|
||||
"email@example.test",
|
||||
"groupEmailAddress",
|
||||
"group@example.test",
|
||||
"groupUpdateMode",
|
||||
"REMOVE"),
|
||||
MediaType.PLAIN_TEXT_UTF_8,
|
||||
new byte[0]);
|
||||
verifyNoInteractions(iamClient);
|
||||
verifyNoMoreInteractions(connection);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -83,6 +90,6 @@ public class DeleteUserCommandTest extends CommandTestCase<DeleteUserCommand> {
|
||||
.hasMessageThat()
|
||||
.isEqualTo("Email does not correspond to a valid user");
|
||||
verifyNoInteractions(iamClient);
|
||||
cloudTasksHelper.assertNoTasksEnqueued("console-user-group-update");
|
||||
verifyNoInteractions(connection);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,12 +14,13 @@
|
||||
|
||||
package google.registry.tools;
|
||||
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import google.registry.model.console.GlobalRole;
|
||||
import google.registry.model.console.RegistrarRole;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.model.console.UserDao;
|
||||
import google.registry.model.console.UserRoles;
|
||||
import google.registry.testing.DatabaseHelper;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -28,8 +29,7 @@ public class GetUserCommandTest extends CommandTestCase<GetUserCommand> {
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
User.ID_GENERATOR_FOR_TESTING.set(0L);
|
||||
UserDao.saveUser(
|
||||
DatabaseHelper.putInDb(
|
||||
new User.Builder()
|
||||
.setEmailAddress("johndoe@theregistrar.com")
|
||||
.setUserRoles(
|
||||
@@ -37,8 +37,7 @@ public class GetUserCommandTest extends CommandTestCase<GetUserCommand> {
|
||||
.setRegistrarRoles(
|
||||
ImmutableMap.of("TheRegistrar", RegistrarRole.PRIMARY_CONTACT))
|
||||
.build())
|
||||
.build());
|
||||
UserDao.saveUser(
|
||||
.build(),
|
||||
new User.Builder()
|
||||
.setEmailAddress("fte@google.com")
|
||||
.setUserRoles(
|
||||
@@ -53,7 +52,6 @@ public class GetUserCommandTest extends CommandTestCase<GetUserCommand> {
|
||||
"""
|
||||
User: {
|
||||
emailAddress=fte@google.com
|
||||
id=1
|
||||
registryLockEmailAddress=null
|
||||
registryLockPasswordHash=null
|
||||
registryLockPasswordSalt=null
|
||||
@@ -76,7 +74,6 @@ public class GetUserCommandTest extends CommandTestCase<GetUserCommand> {
|
||||
"""
|
||||
User: {
|
||||
emailAddress=johndoe@theregistrar.com
|
||||
id=0
|
||||
registryLockEmailAddress=null
|
||||
registryLockPasswordHash=null
|
||||
registryLockPasswordSalt=null
|
||||
@@ -91,7 +88,6 @@ public class GetUserCommandTest extends CommandTestCase<GetUserCommand> {
|
||||
}
|
||||
User: {
|
||||
emailAddress=fte@google.com
|
||||
id=1
|
||||
registryLockEmailAddress=null
|
||||
registryLockPasswordHash=null
|
||||
registryLockPasswordSalt=null
|
||||
@@ -114,7 +110,6 @@ public class GetUserCommandTest extends CommandTestCase<GetUserCommand> {
|
||||
"""
|
||||
User: {
|
||||
emailAddress=johndoe@theregistrar.com
|
||||
id=0
|
||||
registryLockEmailAddress=null
|
||||
registryLockPasswordHash=null
|
||||
registryLockPasswordSalt=null
|
||||
|
||||
@@ -22,9 +22,11 @@ import static google.registry.model.tld.Tld.TldState.GENERAL_AVAILABILITY;
|
||||
import static google.registry.model.tld.Tld.TldState.START_DATE_SUNRISE;
|
||||
import static google.registry.testing.CertificateSamples.SAMPLE_CERT_HASH;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.loadExistingUser;
|
||||
import static google.registry.testing.DatabaseHelper.loadRegistrar;
|
||||
import static google.registry.testing.DatabaseHelper.persistPremiumList;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.testing.DatabaseHelper.putInDb;
|
||||
import static org.joda.money.CurrencyUnit.USD;
|
||||
import static org.joda.time.DateTimeZone.UTC;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
@@ -39,7 +41,6 @@ import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedMap;
|
||||
import google.registry.model.console.GlobalRole;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.model.console.UserDao;
|
||||
import google.registry.model.console.UserRoles;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.model.tld.Tld;
|
||||
@@ -447,12 +448,11 @@ class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
|
||||
|
||||
@Test
|
||||
void testFailure_userExists() {
|
||||
User user =
|
||||
putInDb(
|
||||
new User.Builder()
|
||||
.setEmailAddress("contact@email.com")
|
||||
.setUserRoles(new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).build())
|
||||
.build();
|
||||
UserDao.saveUser(user);
|
||||
.build());
|
||||
IllegalStateException thrown =
|
||||
assertThrows(
|
||||
IllegalStateException.class,
|
||||
@@ -494,12 +494,11 @@ class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
|
||||
|
||||
@Test
|
||||
void testSuccess_userExists_replaceExisting() throws Exception {
|
||||
User user =
|
||||
putInDb(
|
||||
new User.Builder()
|
||||
.setEmailAddress("contact@email.com")
|
||||
.setUserRoles(new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).build())
|
||||
.build();
|
||||
UserDao.saveUser(user);
|
||||
.build());
|
||||
|
||||
runCommandForced(
|
||||
"--overwrite",
|
||||
@@ -520,7 +519,7 @@ class SetupOteCommandTest extends CommandTestCase<SetupOteCommand> {
|
||||
verifyUser("blobio-5", "contact@email.com");
|
||||
|
||||
// verify that the role is completely replaced, e.g., the global role is gone.
|
||||
assertThat(UserDao.loadUser("contact@email.com").get().getUserRoles().getGlobalRole())
|
||||
assertThat(loadExistingUser("contact@email.com").getUserRoles().getGlobalRole())
|
||||
.isEqualTo(GlobalRole.NONE);
|
||||
|
||||
verifyIapPermission("contact@email.com");
|
||||
|
||||
@@ -15,13 +15,14 @@
|
||||
package google.registry.tools;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.testing.DatabaseHelper.loadExistingUser;
|
||||
import static google.registry.testing.DatabaseHelper.putInDb;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import google.registry.model.console.GlobalRole;
|
||||
import google.registry.model.console.RegistrarRole;
|
||||
import google.registry.model.console.User;
|
||||
import google.registry.model.console.UserDao;
|
||||
import google.registry.model.console.UserRoles;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -31,7 +32,7 @@ public class UpdateUserCommandTest extends CommandTestCase<UpdateUserCommand> {
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() throws Exception {
|
||||
UserDao.saveUser(
|
||||
putInDb(
|
||||
new User.Builder()
|
||||
.setEmailAddress("user@example.test")
|
||||
.setUserRoles(new UserRoles.Builder().build())
|
||||
@@ -45,41 +46,39 @@ public class UpdateUserCommandTest extends CommandTestCase<UpdateUserCommand> {
|
||||
"user@example.test",
|
||||
"--registry_lock_email_address",
|
||||
"registrylockemail@otherexample.test");
|
||||
assertThat(UserDao.loadUser("user@example.test").get().getRegistryLockEmailAddress())
|
||||
assertThat(loadExistingUser("user@example.test").getRegistryLockEmailAddress())
|
||||
.hasValue("registrylockemail@otherexample.test");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_removeRegistryLockEmail() throws Exception {
|
||||
UserDao.saveUser(
|
||||
UserDao.loadUser("user@example.test")
|
||||
.get()
|
||||
putInDb(
|
||||
loadExistingUser("user@example.test")
|
||||
.asBuilder()
|
||||
.setRegistryLockEmailAddress("registrylock@otherexample.test")
|
||||
.build());
|
||||
runCommandForced("--email", "user@example.test", "--registry_lock_email_address", "");
|
||||
assertThat(UserDao.loadUser("user@example.test").get().getRegistryLockEmailAddress()).isEmpty();
|
||||
assertThat(loadExistingUser("user@example.test").getRegistryLockEmailAddress()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_admin() throws Exception {
|
||||
assertThat(UserDao.loadUser("user@example.test").get().getUserRoles().isAdmin()).isFalse();
|
||||
assertThat(loadExistingUser("user@example.test").getUserRoles().isAdmin()).isFalse();
|
||||
runCommandForced("--email", "user@example.test", "--admin", "true");
|
||||
assertThat(UserDao.loadUser("user@example.test").get().getUserRoles().isAdmin()).isTrue();
|
||||
assertThat(loadExistingUser("user@example.test").getUserRoles().isAdmin()).isTrue();
|
||||
runCommandForced("--email", "user@example.test", "--admin", "false");
|
||||
assertThat(UserDao.loadUser("user@example.test").get().getUserRoles().isAdmin()).isFalse();
|
||||
assertThat(loadExistingUser("user@example.test").getUserRoles().isAdmin()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_registrarRoles() throws Exception {
|
||||
assertThat(UserDao.loadUser("user@example.test").get().getUserRoles().getRegistrarRoles())
|
||||
.isEmpty();
|
||||
assertThat(loadExistingUser("user@example.test").getUserRoles().getRegistrarRoles()).isEmpty();
|
||||
runCommandForced(
|
||||
"--email",
|
||||
"user@example.test",
|
||||
"--registrar_roles",
|
||||
"TheRegistrar=ACCOUNT_MANAGER,NewRegistrar=PRIMARY_CONTACT");
|
||||
assertThat(UserDao.loadUser("user@example.test").get().getUserRoles().getRegistrarRoles())
|
||||
assertThat(loadExistingUser("user@example.test").getUserRoles().getRegistrarRoles())
|
||||
.isEqualTo(
|
||||
ImmutableMap.of(
|
||||
"TheRegistrar",
|
||||
@@ -87,16 +86,15 @@ public class UpdateUserCommandTest extends CommandTestCase<UpdateUserCommand> {
|
||||
"NewRegistrar",
|
||||
RegistrarRole.PRIMARY_CONTACT));
|
||||
runCommandForced("--email", "user@example.test", "--registrar_roles", "");
|
||||
assertThat(UserDao.loadUser("user@example.test").get().getUserRoles().getRegistrarRoles())
|
||||
.isEmpty();
|
||||
assertThat(loadExistingUser("user@example.test").getUserRoles().getRegistrarRoles()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_globalRole() throws Exception {
|
||||
assertThat(UserDao.loadUser("user@example.test").get().getUserRoles().getGlobalRole())
|
||||
assertThat(loadExistingUser("user@example.test").getUserRoles().getGlobalRole())
|
||||
.isEqualTo(GlobalRole.NONE);
|
||||
runCommandForced("--email", "user@example.test", "--global_role", "FTE");
|
||||
assertThat(UserDao.loadUser("user@example.test").get().getUserRoles().getGlobalRole())
|
||||
assertThat(loadExistingUser("user@example.test").getUserRoles().getGlobalRole())
|
||||
.isEqualTo(GlobalRole.FTE);
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ public class ConsoleRegistryLockVerifyActionTest {
|
||||
assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
|
||||
assertThat(response.getPayload())
|
||||
.isEqualTo(
|
||||
"{\"action\":\"unlocked\",\"domainName\":\"example.test\",\"registrarId\":\"TheRegistrar\"}");
|
||||
"{\"action\":\"locked\",\"domainName\":\"example.test\",\"registrarId\":\"TheRegistrar\"}");
|
||||
assertThat(loadByEntity(defaultDomain).getStatusValues())
|
||||
.containsAtLeastElementsIn(REGISTRY_LOCK_STATUSES);
|
||||
}
|
||||
@@ -123,7 +123,7 @@ public class ConsoleRegistryLockVerifyActionTest {
|
||||
assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
|
||||
assertThat(response.getPayload())
|
||||
.isEqualTo(
|
||||
"{\"action\":\"unlocked\",\"domainName\":\"example.test\",\"registrarId\":\"TheRegistrar\"}");
|
||||
"{\"action\":\"locked\",\"domainName\":\"example.test\",\"registrarId\":\"TheRegistrar\"}");
|
||||
assertThat(loadByEntity(defaultDomain).getStatusValues())
|
||||
.containsAtLeastElementsIn(REGISTRY_LOCK_STATUSES);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ package google.registry.ui.server.console.settings;
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.registrar.RegistrarPocBase.Type.ADMIN;
|
||||
import static google.registry.model.registrar.RegistrarPocBase.Type.WHOIS;
|
||||
import static google.registry.testing.DatabaseHelper.createAdminUser;
|
||||
import static google.registry.testing.DatabaseHelper.insertInDb;
|
||||
import static google.registry.testing.DatabaseHelper.loadAllOf;
|
||||
@@ -67,7 +66,7 @@ class ContactActionTest {
|
||||
+ "\"emailAddress\":\"test.registrar1@example.com\","
|
||||
+ "\"registrarId\":\"registrarId\","
|
||||
+ "\"phoneNumber\":\"+1.9999999999\",\"faxNumber\":\"+1.9999999991\","
|
||||
+ "\"types\":[\"WHOIS\",\"ADMIN\"],\"visibleInWhoisAsAdmin\":true,"
|
||||
+ "\"types\":[\"ADMIN\"],\"visibleInWhoisAsAdmin\":true,"
|
||||
+ "\"visibleInWhoisAsTech\":false,\"visibleInDomainWhoisAsAbuse\":false}";
|
||||
|
||||
private static String jsonRegistrar2 =
|
||||
@@ -75,7 +74,7 @@ class ContactActionTest {
|
||||
+ "\"emailAddress\":\"test.registrar2@example.com\","
|
||||
+ "\"registrarId\":\"registrarId\","
|
||||
+ "\"phoneNumber\":\"+1.1234567890\",\"faxNumber\":\"+1.1234567891\","
|
||||
+ "\"types\":[\"WHOIS\",\"ADMIN\"],\"visibleInWhoisAsAdmin\":true,"
|
||||
+ "\"types\":[\"ADMIN\"],\"visibleInWhoisAsAdmin\":true,"
|
||||
+ "\"visibleInWhoisAsTech\":false,\"visibleInDomainWhoisAsAbuse\":false}";
|
||||
|
||||
private Registrar testRegistrar;
|
||||
@@ -97,7 +96,7 @@ class ContactActionTest {
|
||||
.setEmailAddress("test.registrar1@example.com")
|
||||
.setPhoneNumber("+1.9999999999")
|
||||
.setFaxNumber("+1.9999999991")
|
||||
.setTypes(ImmutableSet.of(WHOIS, ADMIN))
|
||||
.setTypes(ImmutableSet.of(ADMIN))
|
||||
.setVisibleInWhoisAsAdmin(true)
|
||||
.setVisibleInWhoisAsTech(false)
|
||||
.setVisibleInDomainWhoisAsAbuse(false)
|
||||
@@ -218,22 +217,22 @@ class ContactActionTest {
|
||||
+ " {name=Test Registrar 1,"
|
||||
+ " emailAddress=test.registrar1@example.com, registrarId=registrarId,"
|
||||
+ " registryLockEmailAddress=null, phoneNumber=+1.9999999999,"
|
||||
+ " faxNumber=+1.9999999991, types=[ADMIN, WHOIS],"
|
||||
+ " faxNumber=+1.9999999991, types=[ADMIN],"
|
||||
+ " visibleInWhoisAsAdmin=true, visibleInWhoisAsTech=false,"
|
||||
+ " visibleInDomainWhoisAsAbuse=false,"
|
||||
+ " allowedToSetRegistryLockPassword=false}\n"
|
||||
+ " REMOVED:\n"
|
||||
+ " {name=Test Registrar 1, emailAddress=incorrect@email.com,"
|
||||
+ " registrarId=registrarId, registryLockEmailAddress=null,"
|
||||
+ " phoneNumber=+1.9999999999, faxNumber=+1.9999999991, types=[WHOIS,"
|
||||
+ " ADMIN], visibleInWhoisAsAdmin=true,"
|
||||
+ " phoneNumber=+1.9999999999, faxNumber=+1.9999999991, types=[ADMIN],"
|
||||
+ " visibleInWhoisAsAdmin=true,"
|
||||
+ " visibleInWhoisAsTech=false, visibleInDomainWhoisAsAbuse=false,"
|
||||
+ " allowedToSetRegistryLockPassword=false}\n"
|
||||
+ " FINAL CONTENTS:\n"
|
||||
+ " {name=Test Registrar 1,"
|
||||
+ " emailAddress=test.registrar1@example.com, registrarId=registrarId,"
|
||||
+ " registryLockEmailAddress=null, phoneNumber=+1.9999999999,"
|
||||
+ " faxNumber=+1.9999999991, types=[ADMIN, WHOIS],"
|
||||
+ " faxNumber=+1.9999999991, types=[ADMIN],"
|
||||
+ " visibleInWhoisAsAdmin=true, visibleInWhoisAsTech=false,"
|
||||
+ " visibleInDomainWhoisAsAbuse=false,"
|
||||
+ " allowedToSetRegistryLockPassword=false}\n")
|
||||
|
||||
@@ -104,6 +104,8 @@ public class WhoisRegistrarFieldsActionTest {
|
||||
ImmutableMap.of(
|
||||
"whoisServer",
|
||||
"whois.nic.google",
|
||||
"icannReferralEmail",
|
||||
"lol@sloth.test",
|
||||
"phoneNumber",
|
||||
"+1.4155552671",
|
||||
"faxNumber",
|
||||
|
||||
@@ -29,6 +29,8 @@ import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STAT
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSortedMap;
|
||||
import google.registry.model.common.FeatureFlag;
|
||||
import google.registry.model.console.RegistrarRole;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.domain.RegistryLock;
|
||||
@@ -110,15 +112,6 @@ class RegistrarConsoleScreenshotTest extends WebDriverTestCase {
|
||||
driver.diffPage("page");
|
||||
}
|
||||
|
||||
/** Admins shouldn't have the "add" button */
|
||||
@RetryingTest(3)
|
||||
void settingsContact_asAdmin() throws Throwable {
|
||||
server.setIsAdmin(true);
|
||||
driver.get(server.getUrl("/registrar?clientId=NewRegistrar#contact-settings"));
|
||||
driver.waitForDisplayedElement(By.tagName("h1"));
|
||||
driver.diffPage("page");
|
||||
}
|
||||
|
||||
@RetryingTest(3)
|
||||
void settingsContactItem() throws Throwable {
|
||||
driver.get(server.getUrl("/registrar#contact-settings/johndoe@theregistrar.com"));
|
||||
@@ -518,6 +511,18 @@ class RegistrarConsoleScreenshotTest extends WebDriverTestCase {
|
||||
driver.diffPage("page");
|
||||
}
|
||||
|
||||
@RetryingTest(3)
|
||||
void deprecationWarning_active() throws Throwable {
|
||||
persistResource(
|
||||
new FeatureFlag.Builder()
|
||||
.setFeatureName(FeatureFlag.FeatureName.NEW_CONSOLE)
|
||||
.setStatusMap(ImmutableSortedMap.of(START_OF_TIME, FeatureFlag.FeatureStatus.ACTIVE))
|
||||
.build());
|
||||
driver.get(server.getUrl("/registrar"));
|
||||
driver.waitForDisplayedElement(By.tagName("h1"));
|
||||
driver.diffPage("page");
|
||||
}
|
||||
|
||||
private static void createDomainAndSaveLock() {
|
||||
createTld("tld");
|
||||
Domain domain = persistActiveDomain("example.tld");
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<update>
|
||||
<domain:update
|
||||
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>example.tld</domain:name>
|
||||
<domain:add>
|
||||
<domain:ns>
|
||||
<domain:hostObj>ns2.example.foo</domain:hostObj>
|
||||
</domain:ns>
|
||||
<domain:contact type="tech">mak21</domain:contact>
|
||||
<domain:status s="clientHold"
|
||||
lang="en">Payment overdue.</domain:status>
|
||||
</domain:add>
|
||||
<domain:rem>
|
||||
<domain:ns>
|
||||
<domain:hostObj>ns1.example.foo</domain:hostObj>
|
||||
</domain:ns>
|
||||
<domain:contact type="tech">sh8013</domain:contact>
|
||||
<domain:status s="clientUpdateProhibited"/>
|
||||
</domain:rem>
|
||||
</domain:update>
|
||||
</update>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 207 KiB After Width: | Height: | Size: 206 KiB |
|
Before Width: | Height: | Size: 206 KiB After Width: | Height: | Size: 206 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 150 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 97 KiB |
@@ -261,11 +261,11 @@ td.section {
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="property_name">generated on</td>
|
||||
<td class="property_value">2024-07-30 18:27:56</td>
|
||||
<td class="property_value">2024-08-14 16:47:59</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="property_name">last flyway file</td>
|
||||
<td id="lastFlywayFile" class="property_value">V175__user_update_history_id.sql</td>
|
||||
<td id="lastFlywayFile" class="property_value">V178__drop_user_id_history.sql</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -280,7 +280,7 @@ td.section {
|
||||
<text text-anchor="start" x="3795" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">generated by</text>
|
||||
<text text-anchor="start" x="3878" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">SchemaCrawler 16.21.4</text>
|
||||
<text text-anchor="start" x="3794" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">generated on</text>
|
||||
<text text-anchor="start" x="3878" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">2024-07-30 18:27:56</text>
|
||||
<text text-anchor="start" x="3878" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">2024-08-14 16:47:59</text>
|
||||
<polygon fill="none" stroke="#888888" points="3791,-4 3791,-44 4027,-44 4027,-4 3791,-4" /> <!-- allocationtoken_a08ccbef -->
|
||||
<g id="node1" class="node">
|
||||
<title>
|
||||
@@ -348,96 +348,96 @@ td.section {
|
||||
<title>
|
||||
billingevent_a57d1815:w->allocationtoken_a08ccbef:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M2976.47,-1166.26C2968.82,-1148.77 2990.03,-1107.97 2966,-1088.5 2912.26,-1044.95 2724.52,-1069.92 2656,-1060.5 2586.15,-1050.89 1512.01,-836.04 1376.81,-822.2" />
|
||||
<path fill="none" stroke="black" d="M2976.47,-1166.26C2968.82,-1148.77 2990.03,-1107.97 2966,-1088.5 2912.26,-1044.95 2724.52,-1069.92 2656,-1060.5 2514.6,-1041.05 1552.85,-830.4 1376.53,-821.77" />
|
||||
<polygon fill="black" stroke="black" points="2983.61,-1169.93 2990.44,-1178.5 2988.05,-1172.21 2992.5,-1174.5 2992.5,-1174.5 2992.5,-1174.5 2988.05,-1172.21 2994.56,-1170.5 2983.61,-1169.93 2983.61,-1169.93" />
|
||||
<ellipse fill="none" stroke="black" cx="2980.05" cy="-1168.1" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="1367.16,-826.56 1367.84,-816.58 1369.83,-816.71 1369.16,-826.69 1367.16,-826.56" />
|
||||
<polyline fill="none" stroke="black" points="1366.5,-821.5 1371.49,-821.84 " />
|
||||
<polygon fill="black" stroke="black" points="1372.15,-826.89 1372.82,-816.92 1374.82,-817.05 1374.14,-827.03 1372.15,-826.89" />
|
||||
<polyline fill="none" stroke="black" points="1371.49,-821.84 1376.48,-822.18 " />
|
||||
<text text-anchor="start" x="2094.5" y="-996.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_billing_event_allocation_token</text>
|
||||
<polygon fill="black" stroke="black" points="1367.36,-826.53 1367.64,-816.53 1369.63,-816.58 1369.36,-826.58 1367.36,-826.53" />
|
||||
<polyline fill="none" stroke="black" points="1366.5,-821.5 1371.5,-821.64 " />
|
||||
<polygon fill="black" stroke="black" points="1372.36,-826.66 1372.63,-816.67 1374.63,-816.72 1374.36,-826.72 1372.36,-826.66" />
|
||||
<polyline fill="none" stroke="black" points="1371.5,-821.64 1376.5,-821.77 " />
|
||||
<text text-anchor="start" x="2094.5" y="-997.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_billing_event_allocation_token</text>
|
||||
</g> <!-- domainhistory_a54cc226 -->
|
||||
<g id="node4" class="node">
|
||||
<title>
|
||||
domainhistory_a54cc226
|
||||
</title>
|
||||
<polygon fill="#e9c2f2" stroke="transparent" points="2337,-878.5 2337,-897.5 2503,-897.5 2503,-878.5 2337,-878.5" />
|
||||
<text text-anchor="start" x="2339" y="-885.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."DomainHistory"</text>
|
||||
<polygon fill="#e9c2f2" stroke="transparent" points="2503,-878.5 2503,-897.5 2629,-897.5 2629,-878.5 2503,-878.5" />
|
||||
<text text-anchor="start" x="2590" y="-884.3" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
|
||||
<text text-anchor="start" x="2339" y="-866.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">history_revision_id</text>
|
||||
<text text-anchor="start" x="2497" y="-865.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
|
||||
<text text-anchor="start" x="2505" y="-865.3" font-family="Helvetica,sans-Serif" font-size="14.00">int8 not null</text>
|
||||
<text text-anchor="start" x="2339" y="-846.3" font-family="Helvetica,sans-Serif" font-size="14.00">history_registrar_id</text>
|
||||
<text text-anchor="start" x="2497" y="-846.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
|
||||
<text text-anchor="start" x="2505" y="-846.3" font-family="Helvetica,sans-Serif" font-size="14.00">text</text>
|
||||
<text text-anchor="start" x="2339" y="-827.3" font-family="Helvetica,sans-Serif" font-size="14.00">history_modification_time</text>
|
||||
<text text-anchor="start" x="2497" y="-827.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
|
||||
<text text-anchor="start" x="2505" y="-827.3" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz not null</text>
|
||||
<text text-anchor="start" x="2339" y="-808.3" font-family="Helvetica,sans-Serif" font-size="14.00">history_type</text>
|
||||
<text text-anchor="start" x="2497" y="-808.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
|
||||
<text text-anchor="start" x="2505" y="-808.3" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
|
||||
<text text-anchor="start" x="2339" y="-789.3" font-family="Helvetica,sans-Serif" font-size="14.00">creation_time</text>
|
||||
<text text-anchor="start" x="2497" y="-789.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
|
||||
<text text-anchor="start" x="2505" y="-789.3" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz</text>
|
||||
<text text-anchor="start" x="2339" y="-771.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">domain_repo_id</text>
|
||||
<text text-anchor="start" x="2497" y="-770.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
|
||||
<text text-anchor="start" x="2505" y="-770.3" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
|
||||
<text text-anchor="start" x="2339" y="-751.3" font-family="Helvetica,sans-Serif" font-size="14.00">current_package_token</text>
|
||||
<text text-anchor="start" x="2497" y="-751.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
|
||||
<text text-anchor="start" x="2505" y="-751.3" font-family="Helvetica,sans-Serif" font-size="14.00">text</text>
|
||||
<polygon fill="none" stroke="#888888" points="2336,-744.5 2336,-898.5 2630,-898.5 2630,-744.5 2336,-744.5" />
|
||||
<polygon fill="#e9c2f2" stroke="transparent" points="2337,-876.5 2337,-895.5 2503,-895.5 2503,-876.5 2337,-876.5" />
|
||||
<text text-anchor="start" x="2339" y="-883.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."DomainHistory"</text>
|
||||
<polygon fill="#e9c2f2" stroke="transparent" points="2503,-876.5 2503,-895.5 2629,-895.5 2629,-876.5 2503,-876.5" />
|
||||
<text text-anchor="start" x="2590" y="-882.3" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
|
||||
<text text-anchor="start" x="2339" y="-864.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">history_revision_id</text>
|
||||
<text text-anchor="start" x="2497" y="-863.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
|
||||
<text text-anchor="start" x="2505" y="-863.3" font-family="Helvetica,sans-Serif" font-size="14.00">int8 not null</text>
|
||||
<text text-anchor="start" x="2339" y="-844.3" font-family="Helvetica,sans-Serif" font-size="14.00">history_registrar_id</text>
|
||||
<text text-anchor="start" x="2497" y="-844.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
|
||||
<text text-anchor="start" x="2505" y="-844.3" font-family="Helvetica,sans-Serif" font-size="14.00">text</text>
|
||||
<text text-anchor="start" x="2339" y="-825.3" font-family="Helvetica,sans-Serif" font-size="14.00">history_modification_time</text>
|
||||
<text text-anchor="start" x="2497" y="-825.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
|
||||
<text text-anchor="start" x="2505" y="-825.3" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz not null</text>
|
||||
<text text-anchor="start" x="2339" y="-806.3" font-family="Helvetica,sans-Serif" font-size="14.00">history_type</text>
|
||||
<text text-anchor="start" x="2497" y="-806.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
|
||||
<text text-anchor="start" x="2505" y="-806.3" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
|
||||
<text text-anchor="start" x="2339" y="-787.3" font-family="Helvetica,sans-Serif" font-size="14.00">creation_time</text>
|
||||
<text text-anchor="start" x="2497" y="-787.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
|
||||
<text text-anchor="start" x="2505" y="-787.3" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz</text>
|
||||
<text text-anchor="start" x="2339" y="-769.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">domain_repo_id</text>
|
||||
<text text-anchor="start" x="2497" y="-768.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
|
||||
<text text-anchor="start" x="2505" y="-768.3" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
|
||||
<text text-anchor="start" x="2339" y="-749.3" font-family="Helvetica,sans-Serif" font-size="14.00">current_package_token</text>
|
||||
<text text-anchor="start" x="2497" y="-749.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
|
||||
<text text-anchor="start" x="2505" y="-749.3" font-family="Helvetica,sans-Serif" font-size="14.00">text</text>
|
||||
<polygon fill="none" stroke="#888888" points="2336,-742.5 2336,-896.5 2630,-896.5 2630,-742.5 2336,-742.5" />
|
||||
</g> <!-- billingevent_a57d1815->domainhistory_a54cc226 -->
|
||||
<g id="edge31" class="edge">
|
||||
<title>
|
||||
billingevent_a57d1815:w->domainhistory_a54cc226:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M2976.47,-1205.25C2946.11,-1162.93 3005.94,-970.66 2966,-931.5 2916.68,-883.14 2707.6,-954.43 2656,-908.5 2613.3,-870.49 2681.22,-785.44 2640.12,-774.64" />
|
||||
<path fill="none" stroke="black" d="M2976.47,-1205.25C2946.11,-1162.93 3005.94,-970.66 2966,-931.5 2916.68,-883.14 2707.54,-954.5 2656,-908.5 2612.65,-869.81 2682.2,-783.25 2640,-772.59" />
|
||||
<polygon fill="black" stroke="black" points="2983.61,-1208.92 2990.44,-1217.5 2988.05,-1211.21 2992.5,-1213.5 2992.5,-1213.5 2992.5,-1213.5 2988.05,-1211.21 2994.56,-1209.5 2983.61,-1208.92 2983.61,-1208.92" />
|
||||
<ellipse fill="none" stroke="black" cx="2980.05" cy="-1207.09" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="2630.44,-778.58 2631.55,-768.64 2633.54,-768.87 2632.42,-778.8 2630.44,-778.58" />
|
||||
<polyline fill="none" stroke="black" points="2630,-773.5 2634.97,-774.06 " />
|
||||
<polygon fill="black" stroke="black" points="2635.4,-779.14 2636.52,-769.2 2638.51,-769.42 2637.39,-779.36 2635.4,-779.14" />
|
||||
<polyline fill="none" stroke="black" points="2634.97,-774.06 2639.94,-774.62 " />
|
||||
<polygon fill="black" stroke="black" points="2630.45,-776.58 2631.53,-766.64 2633.52,-766.85 2632.44,-776.79 2630.45,-776.58" />
|
||||
<polyline fill="none" stroke="black" points="2630,-771.5 2634.97,-772.04 " />
|
||||
<polygon fill="black" stroke="black" points="2635.43,-777.12 2636.5,-767.18 2638.49,-767.39 2637.41,-777.33 2635.43,-777.12" />
|
||||
<polyline fill="none" stroke="black" points="2634.97,-772.04 2639.94,-772.58 " />
|
||||
<text text-anchor="start" x="2714.5" y="-935.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_billing_event_domain_history</text>
|
||||
</g> <!-- billingevent_a57d1815->domainhistory_a54cc226 -->
|
||||
<g id="edge32" class="edge">
|
||||
<title>
|
||||
billingevent_a57d1815:w->domainhistory_a54cc226:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M2976.8,-1223.36C2971.31,-1207.82 2984.56,-1176.21 2966,-1158.5 2861.76,-1059 2749.2,-1173.41 2656,-1063.5 2630.4,-1033.31 2665.89,-897.37 2639.68,-873.19" />
|
||||
<polygon fill="black" stroke="black" points="2983.86,-1227.47 2990.24,-1236.39 2988.18,-1229.98 2992.5,-1232.5 2992.5,-1232.5 2992.5,-1232.5 2988.18,-1229.98 2994.76,-1228.61 2983.86,-1227.47 2983.86,-1227.47" />
|
||||
<ellipse fill="none" stroke="black" cx="2980.4" cy="-1225.46" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="2629.16,-874.53 2632.71,-865.18 2634.58,-865.89 2631.03,-875.24 2629.16,-874.53" />
|
||||
<polyline fill="none" stroke="black" points="2630,-869.5 2634.67,-871.28 " />
|
||||
<polygon fill="black" stroke="black" points="2633.83,-876.31 2637.39,-866.96 2639.26,-867.67 2635.7,-877.02 2633.83,-876.31" />
|
||||
<polyline fill="none" stroke="black" points="2634.67,-871.28 2639.35,-873.06 " />
|
||||
<text text-anchor="start" x="2714.5" y="-1162.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_billing_event_domain_history</text>
|
||||
<path fill="none" stroke="black" d="M2976.66,-1223.23C2971.2,-1207.48 2984.77,-1175.44 2966,-1157.5 2861.92,-1058.02 2749.2,-1173.23 2656,-1063.5 2630,-1032.89 2666.52,-894.48 2639.43,-870.92" />
|
||||
<polygon fill="black" stroke="black" points="2983.87,-1227.45 2990.23,-1236.38 2988.18,-1229.97 2992.5,-1232.5 2992.5,-1232.5 2992.5,-1232.5 2988.18,-1229.97 2994.77,-1228.62 2983.87,-1227.45 2983.87,-1227.45" />
|
||||
<ellipse fill="none" stroke="black" cx="2980.42" cy="-1225.43" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="2629.24,-872.54 2632.64,-863.14 2634.52,-863.82 2631.12,-873.22 2629.24,-872.54" />
|
||||
<polyline fill="none" stroke="black" points="2630,-867.5 2634.7,-869.2 " />
|
||||
<polygon fill="black" stroke="black" points="2633.94,-874.24 2637.34,-864.84 2639.22,-865.52 2635.82,-874.93 2633.94,-874.24" />
|
||||
<polyline fill="none" stroke="black" points="2634.7,-869.2 2639.4,-870.91 " />
|
||||
<text text-anchor="start" x="2714.5" y="-1161.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_billing_event_domain_history</text>
|
||||
</g> <!-- billingevent_a57d1815->domainhistory_a54cc226 -->
|
||||
<g id="edge33" class="edge">
|
||||
<title>
|
||||
billingevent_a57d1815:w->domainhistory_a54cc226:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M2976.93,-1204.14C2952.84,-1163.02 3000.98,-998.93 2966,-965.5 2916.11,-917.81 2706.9,-993.11 2656,-946.5 2630.13,-922.81 2661.43,-801.01 2639.23,-777.45" />
|
||||
<path fill="none" stroke="black" d="M2976.93,-1204.14C2952.84,-1163.02 3000.98,-998.93 2966,-965.5 2916.11,-917.81 2706.86,-993.15 2656,-946.5 2629.86,-922.52 2661.74,-799.33 2639.33,-775.49" />
|
||||
<polygon fill="black" stroke="black" points="2983.93,-1208.35 2990.18,-1217.36 2988.21,-1210.92 2992.5,-1213.5 2992.5,-1213.5 2992.5,-1213.5 2988.21,-1210.92 2994.82,-1209.64 2983.93,-1208.35 2983.93,-1208.35" />
|
||||
<ellipse fill="none" stroke="black" cx="2980.5" cy="-1206.29" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="2628.95,-778.49 2632.89,-769.3 2634.73,-770.08 2630.79,-779.28 2628.95,-778.49" />
|
||||
<polyline fill="none" stroke="black" points="2630,-773.5 2634.6,-775.47 " />
|
||||
<polygon fill="black" stroke="black" points="2633.55,-780.46 2637.48,-771.26 2639.32,-772.05 2635.39,-781.24 2633.55,-780.46" />
|
||||
<polyline fill="none" stroke="black" points="2634.6,-775.47 2639.19,-777.43 " />
|
||||
<polygon fill="black" stroke="black" points="2628.95,-776.49 2632.89,-767.3 2634.73,-768.09 2630.79,-777.28 2628.95,-776.49" />
|
||||
<polyline fill="none" stroke="black" points="2630,-771.5 2634.6,-773.47 " />
|
||||
<polygon fill="black" stroke="black" points="2633.55,-778.46 2637.48,-769.27 2639.32,-770.05 2635.38,-779.25 2633.55,-778.46" />
|
||||
<polyline fill="none" stroke="black" points="2634.6,-773.47 2639.19,-775.44 " />
|
||||
<text text-anchor="start" x="2704.5" y="-969.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_billing_event_recurrence_history</text>
|
||||
</g> <!-- billingevent_a57d1815->domainhistory_a54cc226 -->
|
||||
<g id="edge34" class="edge">
|
||||
<title>
|
||||
billingevent_a57d1815:w->domainhistory_a54cc226:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M2978.52,-1087.04C2975.97,-1074.58 2980.08,-1055.17 2966,-1045.5 2908.95,-1006.32 2706.85,-1062.45 2656,-1015.5 2610.41,-973.41 2686.03,-881.18 2640.06,-870.51" />
|
||||
<path fill="none" stroke="black" d="M2978.52,-1087.04C2975.97,-1074.58 2980.08,-1055.17 2966,-1045.5 2908.95,-1006.32 2706.8,-1062.51 2656,-1015.5 2609.86,-972.8 2686.74,-879.33 2640.19,-868.52" />
|
||||
<polygon fill="black" stroke="black" points="2984.77,-1092.16 2989.65,-1101.98 2988.63,-1095.33 2992.5,-1098.5 2992.5,-1098.5 2992.5,-1098.5 2988.63,-1095.33 2995.35,-1095.02 2984.77,-1092.16 2984.77,-1092.16" />
|
||||
<ellipse fill="none" stroke="black" cx="2981.67" cy="-1089.62" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="2630.49,-874.57 2631.5,-864.63 2633.49,-864.83 2632.48,-874.78 2630.49,-874.57" />
|
||||
<polyline fill="none" stroke="black" points="2630,-869.5 2634.97,-870 " />
|
||||
<polygon fill="black" stroke="black" points="2635.47,-875.08 2636.47,-865.13 2638.46,-865.33 2637.46,-875.28 2635.47,-875.08" />
|
||||
<polyline fill="none" stroke="black" points="2634.97,-870 2639.95,-870.5 " />
|
||||
<polygon fill="black" stroke="black" points="2630.49,-872.58 2631.5,-862.63 2633.49,-862.83 2632.48,-872.78 2630.49,-872.58" />
|
||||
<polyline fill="none" stroke="black" points="2630,-867.5 2634.97,-868 " />
|
||||
<polygon fill="black" stroke="black" points="2635.47,-873.08 2636.47,-863.13 2638.46,-863.33 2637.46,-873.28 2635.47,-873.08" />
|
||||
<polyline fill="none" stroke="black" points="2634.97,-868 2639.95,-868.5 " />
|
||||
<text text-anchor="start" x="2704.5" y="-1049.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_billing_event_recurrence_history</text>
|
||||
</g> <!-- billingrecurrence_5fa2cb01 -->
|
||||
<g id="node7" class="node">
|
||||
@@ -510,14 +510,14 @@ td.section {
|
||||
<title>
|
||||
billingevent_a57d1815:w->registrar_6e1503e3:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M2974.21,-1251.49C2582,-1251.17 2476.21,-1239.98 2078,-1191.5 1897.39,-1169.51 1856.24,-1135.56 1675,-1119.5 1561.67,-1109.46 1532.65,-1114.14 1419,-1119.5 1286.34,-1125.76 322.69,-1155.41 231,-1251.5 194.01,-1290.26 253.88,-1480.65 215.3,-1505.76" />
|
||||
<path fill="none" stroke="black" d="M2974.21,-1251.49C2582,-1251.15 2476.27,-1239.5 2078,-1191.5 1897.44,-1169.74 1856.18,-1136.34 1675,-1120.5 1561.65,-1110.59 1532.66,-1115.3 1419,-1120.5 1286.34,-1126.57 322.68,-1155.42 231,-1251.5 194.01,-1290.26 253.88,-1480.65 215.3,-1505.76" />
|
||||
<polygon fill="black" stroke="black" points="2982.5,-1251.5 2992.5,-1256 2987.5,-1251.5 2992.5,-1251.5 2992.5,-1251.5 2992.5,-1251.5 2987.5,-1251.5 2992.5,-1247 2982.5,-1251.5 2982.5,-1251.5" />
|
||||
<ellipse fill="none" stroke="black" cx="2978.5" cy="-1251.49" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="207.81,-1513.05 205.12,-1503.42 207.04,-1502.88 209.73,-1512.51 207.81,-1513.05" />
|
||||
<polyline fill="none" stroke="black" points="205.5,-1508.5 210.32,-1507.15 " />
|
||||
<polygon fill="black" stroke="black" points="212.62,-1511.7 209.93,-1502.07 211.86,-1501.53 214.55,-1511.16 212.62,-1511.7" />
|
||||
<polyline fill="none" stroke="black" points="210.32,-1507.15 215.13,-1505.81 " />
|
||||
<text text-anchor="start" x="1462.5" y="-1123.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_billing_event_registrar_id</text>
|
||||
<text text-anchor="start" x="1462.5" y="-1124.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_billing_event_registrar_id</text>
|
||||
</g> <!-- domain_6c51cffa -->
|
||||
<g id="node3" class="node">
|
||||
<title>
|
||||
@@ -596,14 +596,14 @@ td.section {
|
||||
<title>
|
||||
domain_6c51cffa:w->allocationtoken_a08ccbef:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M1696.58,-1231.04C1660.47,-1212.8 1718.44,-1126.97 1675,-1082.5 1592.33,-997.86 1495.93,-1099.39 1419,-1009.5 1376.49,-959.83 1426.77,-923.59 1401,-863.5 1393.04,-844.94 1391.16,-828.06 1376.65,-823.02" />
|
||||
<path fill="none" stroke="black" d="M1696.68,-1231.06C1660.76,-1212.94 1718.2,-1127.66 1675,-1083.5 1592.26,-998.93 1495.89,-1100.42 1419,-1010.5 1376.22,-960.47 1426.92,-924 1401,-863.5 1393.05,-844.94 1391.16,-828.06 1376.65,-823.02" />
|
||||
<polygon fill="black" stroke="black" points="1704.68,-1232.6 1713.65,-1238.92 1709.59,-1233.55 1714.5,-1234.5 1714.5,-1234.5 1714.5,-1234.5 1709.59,-1233.55 1715.35,-1230.08 1704.68,-1232.6 1704.68,-1232.6" />
|
||||
<ellipse fill="none" stroke="black" cx="1700.75" cy="-1231.85" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="1366.75,-826.59 1368.23,-816.7 1370.21,-817 1368.73,-826.89 1366.75,-826.59" />
|
||||
<polyline fill="none" stroke="black" points="1366.5,-821.5 1371.44,-822.24 " />
|
||||
<polygon fill="black" stroke="black" points="1371.69,-827.33 1373.18,-817.45 1375.15,-817.74 1373.67,-827.63 1371.69,-827.33" />
|
||||
<polyline fill="none" stroke="black" points="1371.44,-822.24 1376.39,-822.98 " />
|
||||
<text text-anchor="start" x="1441" y="-1086.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_domain_current_package_token</text>
|
||||
<text text-anchor="start" x="1441" y="-1087.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_domain_current_package_token</text>
|
||||
</g> <!-- domain_6c51cffa->billingevent_a57d1815 -->
|
||||
<g id="edge6" class="edge">
|
||||
<title>
|
||||
@@ -656,27 +656,27 @@ td.section {
|
||||
<title>
|
||||
domain_6c51cffa:w->billingcancellation_6eedf614:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M1696.61,-1364.24C1657.67,-1345.95 1720.61,-1255.2 1675,-1208.5 1592.58,-1124.12 1500.81,-1223.47 1419,-1138.5 1384.42,-1102.59 1436.45,-1032.03 1401.64,-1021.76" />
|
||||
<path fill="none" stroke="black" d="M1696.71,-1364.26C1657.97,-1346.09 1720.38,-1255.89 1675,-1209.5 1592.51,-1125.18 1500.73,-1224.55 1419,-1139.5 1384.18,-1103.26 1436.79,-1032.13 1401.72,-1021.77" />
|
||||
<polygon fill="black" stroke="black" points="1704.66,-1365.71 1713.69,-1371.93 1709.58,-1366.6 1714.5,-1367.5 1714.5,-1367.5 1714.5,-1367.5 1709.58,-1366.6 1715.31,-1363.07 1704.66,-1365.71 1704.66,-1365.71" />
|
||||
<ellipse fill="none" stroke="black" cx="1700.73" cy="-1364.99" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="1391.88,-1025.59 1393.11,-1015.66 1395.09,-1015.91 1393.86,-1025.83 1391.88,-1025.59" />
|
||||
<polyline fill="none" stroke="black" points="1391.5,-1020.5 1396.46,-1021.12 " />
|
||||
<polygon fill="black" stroke="black" points="1396.84,-1026.2 1398.07,-1016.28 1400.06,-1016.53 1398.82,-1026.45 1396.84,-1026.2" />
|
||||
<polyline fill="none" stroke="black" points="1396.46,-1021.12 1401.42,-1021.73 " />
|
||||
<text text-anchor="start" x="1419" y="-1212.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_domain_transfer_billing_cancellation_id</text>
|
||||
<text text-anchor="start" x="1419" y="-1213.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_domain_transfer_billing_cancellation_id</text>
|
||||
</g> <!-- domain_6c51cffa->billingrecurrence_5fa2cb01 -->
|
||||
<g id="edge10" class="edge">
|
||||
<title>
|
||||
domain_6c51cffa:w->billingrecurrence_5fa2cb01:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M1697.22,-1267.32C1677.12,-1249.49 1709.18,-1190.36 1675,-1163.5 1630,-1128.14 1475.52,-1144.48 1419,-1135.5 1262.5,-1110.63 1218.4,-1118.09 1070,-1062.5 935.47,-1012.1 875.64,-1018.34 788,-904.5 762.77,-871.73 799.98,-816.6 772.61,-806.96" />
|
||||
<polygon fill="black" stroke="black" points="1704.92,-1269.63 1713.21,-1276.81 1709.71,-1271.06 1714.5,-1272.5 1714.5,-1272.5 1714.5,-1272.5 1709.71,-1271.06 1715.79,-1268.19 1704.92,-1269.63 1704.92,-1269.63" />
|
||||
<ellipse fill="none" stroke="black" cx="1701.09" cy="-1268.48" rx="4" ry="4" />
|
||||
<path fill="none" stroke="black" d="M1697.06,-1267.11C1677.63,-1249.16 1708.79,-1190.97 1675,-1164.5 1629.95,-1129.21 1475.51,-1145.56 1419,-1136.5 1262.44,-1111.4 1218.41,-1118.33 1070,-1062.5 935.54,-1011.91 875.64,-1018.34 788,-904.5 762.77,-871.73 799.98,-816.6 772.61,-806.96" />
|
||||
<polygon fill="black" stroke="black" points="1704.95,-1269.55 1713.17,-1276.8 1709.72,-1271.02 1714.5,-1272.5 1714.5,-1272.5 1714.5,-1272.5 1709.72,-1271.02 1715.83,-1268.2 1704.95,-1269.55 1704.95,-1269.55" />
|
||||
<ellipse fill="none" stroke="black" cx="1701.12" cy="-1268.37" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="762.78,-810.59 764.2,-800.69 766.18,-800.98 764.75,-810.88 762.78,-810.59" />
|
||||
<polyline fill="none" stroke="black" points="762.5,-805.5 767.45,-806.21 " />
|
||||
<polygon fill="black" stroke="black" points="767.72,-811.31 769.15,-801.41 771.13,-801.69 769.7,-811.59 767.72,-811.31" />
|
||||
<polyline fill="none" stroke="black" points="767.45,-806.21 772.4,-806.93 " />
|
||||
<text text-anchor="start" x="1137.5" y="-1136.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_domain_billing_recurrence_id</text>
|
||||
<text text-anchor="start" x="1137.5" y="-1137.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_domain_billing_recurrence_id</text>
|
||||
</g> <!-- domain_6c51cffa->billingrecurrence_5fa2cb01 -->
|
||||
<g id="edge11" class="edge">
|
||||
<title>
|
||||
@@ -878,22 +878,22 @@ td.section {
|
||||
<title>
|
||||
domainhistory_a54cc226:w->allocationtoken_a08ccbef:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M2317.97,-754.39C2209.77,-753.1 2176.62,-740.3 2060,-736.5 1896.98,-731.19 1855.88,-727.9 1693,-736.5 1662.43,-738.11 1446.41,-751.87 1419,-765.5 1391.91,-778.97 1398.41,-812.58 1376.44,-820.03" />
|
||||
<polygon fill="black" stroke="black" points="2326,-754.44 2335.97,-759 2331,-754.47 2336,-754.5 2336,-754.5 2336,-754.5 2331,-754.47 2336.03,-750 2326,-754.44 2326,-754.44" />
|
||||
<ellipse fill="none" stroke="black" cx="2322" cy="-754.42" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="1368.22,-826.3 1366.76,-816.41 1368.73,-816.11 1370.2,-826.01 1368.22,-826.3" />
|
||||
<path fill="none" stroke="black" d="M2317.97,-752.39C2209.77,-751.1 2176.62,-738.3 2060,-734.5 1896.98,-729.19 1855.56,-721.05 1693,-734.5 1684.92,-735.17 1683.03,-736.39 1675,-737.5 1561.62,-753.14 1521.39,-714.35 1419,-765.5 1391.94,-779.02 1398.41,-812.59 1376.44,-820.03" />
|
||||
<polygon fill="black" stroke="black" points="2326,-752.44 2335.97,-757 2331,-752.47 2336,-752.5 2336,-752.5 2336,-752.5 2331,-752.47 2336.03,-748 2326,-752.44 2326,-752.44" />
|
||||
<ellipse fill="none" stroke="black" cx="2322" cy="-752.42" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="1368.22,-826.3 1366.76,-816.41 1368.74,-816.11 1370.2,-826.01 1368.22,-826.3" />
|
||||
<polyline fill="none" stroke="black" points="1366.5,-821.5 1371.45,-820.77 " />
|
||||
<polygon fill="black" stroke="black" points="1373.17,-825.57 1371.7,-815.67 1373.68,-815.38 1375.15,-825.27 1373.17,-825.57" />
|
||||
<polyline fill="none" stroke="black" points="1371.45,-820.77 1376.39,-820.03 " />
|
||||
<text text-anchor="start" x="1747" y="-740.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_domain_history_current_package_token</text>
|
||||
<text text-anchor="start" x="1747" y="-738.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_domain_history_current_package_token</text>
|
||||
</g> <!-- domainhistory_a54cc226->domain_6c51cffa -->
|
||||
<g id="edge24" class="edge">
|
||||
<title>
|
||||
domainhistory_a54cc226:w->domain_6c51cffa:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M2324.79,-787.9C2306.79,-849.87 2333.2,-1091.76 2310,-1115.5 2273.79,-1152.55 2114.36,-1101.59 2078,-1138.5 2044.47,-1172.53 2084.68,-1543.75 2048.18,-1591.46" />
|
||||
<polygon fill="black" stroke="black" points="2329.86,-781.39 2339.55,-776.26 2332.93,-777.45 2336,-773.5 2336,-773.5 2336,-773.5 2332.93,-777.45 2332.45,-770.74 2329.86,-781.39 2329.86,-781.39" />
|
||||
<ellipse fill="none" stroke="black" cx="2327.4" cy="-784.55" rx="4" ry="4" />
|
||||
<path fill="none" stroke="black" d="M2324.73,-785.98C2306.66,-848.31 2333.33,-1091.62 2310,-1115.5 2273.8,-1152.56 2114.36,-1101.59 2078,-1138.5 2044.47,-1172.53 2084.68,-1543.75 2048.18,-1591.46" />
|
||||
<polygon fill="black" stroke="black" points="2329.86,-779.39 2339.55,-774.26 2332.93,-775.45 2336,-771.5 2336,-771.5 2336,-771.5 2332.93,-775.45 2332.45,-768.74 2329.86,-779.39 2329.86,-779.39" />
|
||||
<ellipse fill="none" stroke="black" cx="2327.4" cy="-782.55" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="2042.87,-1600.32 2037.86,-1591.67 2039.59,-1590.67 2044.6,-1599.32 2042.87,-1600.32" />
|
||||
<polyline fill="none" stroke="black" points="2039.5,-1596.5 2043.82,-1593.99 " />
|
||||
<polygon fill="black" stroke="black" points="2047.2,-1597.81 2042.18,-1589.16 2043.91,-1588.16 2048.93,-1596.81 2047.2,-1597.81" />
|
||||
@@ -904,9 +904,9 @@ td.section {
|
||||
<title>
|
||||
domainhistory_a54cc226:w->registrar_6e1503e3:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M2317.98,-849.23C2213.9,-841.75 1694.56,-803.77 1693,-802.5 1670.42,-784.11 1697.19,-758.36 1675,-739.5 1581.57,-660.11 1522.93,-720.32 1401,-707.5 1120.88,-678.05 1051.36,-661.63 770,-648.5 627.49,-641.85 586.15,-609.23 449,-648.5 339.22,-679.94 288.15,-685.63 231,-784.5 212.12,-817.17 241.6,-1424.91 212.2,-1500.75" />
|
||||
<polygon fill="black" stroke="black" points="2326.02,-849.8 2335.68,-854.99 2331.01,-850.15 2336,-850.5 2336,-850.5 2336,-850.5 2331.01,-850.15 2336.32,-846.01 2326.02,-849.8 2326.02,-849.8" />
|
||||
<ellipse fill="none" stroke="black" cx="2322.03" cy="-849.51" rx="4" ry="4" />
|
||||
<path fill="none" stroke="black" d="M2317.98,-847.23C2213.9,-839.75 1694.57,-801.77 1693,-800.5 1671.01,-782.74 1696.62,-757.71 1675,-739.5 1581.23,-660.51 1522.93,-720.32 1401,-707.5 1120.88,-678.05 1051.36,-661.63 770,-648.5 627.49,-641.85 586.15,-609.23 449,-648.5 339.22,-679.94 288.15,-685.63 231,-784.5 212.12,-817.17 241.6,-1424.91 212.2,-1500.75" />
|
||||
<polygon fill="black" stroke="black" points="2326.02,-847.8 2335.68,-852.99 2331.01,-848.15 2336,-848.5 2336,-848.5 2336,-848.5 2331.01,-848.15 2336.32,-844.01 2326.02,-847.8 2326.02,-847.8" />
|
||||
<ellipse fill="none" stroke="black" cx="2322.03" cy="-847.51" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="209.94,-1511.01 202.37,-1504.47 203.68,-1502.96 211.24,-1509.5 209.94,-1511.01" />
|
||||
<polyline fill="none" stroke="black" points="205.5,-1508.5 208.77,-1504.72 " />
|
||||
<polygon fill="black" stroke="black" points="213.21,-1507.23 205.64,-1500.69 206.95,-1499.18 214.51,-1505.72 213.21,-1507.23" />
|
||||
@@ -917,7 +917,7 @@ td.section {
|
||||
<title>
|
||||
billingcancellation_6eedf614:w->billingevent_a57d1815:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M1072.35,-889.39C1073.82,-883.45 1077.2,-877.17 1081.5,-873 1094.16,-860.72 1385.84,-861.26 1399,-873 1428.13,-898.98 1392.03,-1019.28 1419,-1047.5 1431.81,-1060.9 2059.68,-1150.66 2078,-1153.5 2472.31,-1214.52 2610.87,-1103.61 2966,-1285.5 2976.21,-1290.73 2973.43,-1299.54 2984,-1304 3005.21,-1312.96 3381.98,-1320.04 3398.5,-1304 3405.85,-1296.87 3410.61,-1283.71 3408.02,-1276.18" />
|
||||
<path fill="none" stroke="black" d="M1072.35,-889.39C1073.82,-883.45 1077.2,-877.17 1081.5,-873 1094.16,-860.72 1385.84,-861.25 1399,-873 1428.28,-899.14 1391.87,-1020.13 1419,-1048.5 1431.81,-1061.9 2059.68,-1150.68 2078,-1153.5 2472.36,-1214.23 2610.87,-1103.61 2966,-1285.5 2976.21,-1290.73 2973.43,-1299.54 2984,-1304 3005.21,-1312.96 3381.98,-1320.04 3398.5,-1304 3405.85,-1296.87 3410.61,-1283.71 3408.02,-1276.18" />
|
||||
<polygon fill="black" stroke="black" points="1075.98,-896.58 1076.48,-907.53 1078.24,-901.04 1080.5,-905.5 1080.5,-905.5 1080.5,-905.5 1078.24,-901.04 1084.52,-903.47 1075.98,-896.58 1075.98,-896.58" />
|
||||
<ellipse fill="none" stroke="black" cx="1074.18" cy="-893.01" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="3397.56,-1275.22 3403.11,-1266.89 3404.77,-1268 3399.22,-1276.32 3397.56,-1275.22" />
|
||||
@@ -930,26 +930,26 @@ td.section {
|
||||
<title>
|
||||
billingcancellation_6eedf614:w->domainhistory_a54cc226:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M1069.72,-948.03C1065.01,-925.43 1071.43,-883.26 1081.5,-873 1093.94,-860.33 1383.29,-864.77 1401,-863.5 1806.59,-834.32 1946.21,-941.18 2310,-759.5 2320.41,-754.3 2317.31,-745.1 2328,-740.5 2450.89,-687.64 2532.98,-647.35 2629,-740.5 2636.24,-747.52 2640.93,-760.49 2638.39,-767.9" />
|
||||
<path fill="none" stroke="black" d="M1069.72,-948.03C1065.01,-925.43 1071.43,-883.26 1081.5,-873 1093.94,-860.33 1383.29,-864.79 1401,-863.5 1806.66,-833.87 1946.31,-939.62 2310,-757.5 2320.4,-752.29 2317.31,-743.1 2328,-738.5 2450.89,-685.64 2532.98,-645.35 2629,-738.5 2636.24,-745.52 2640.93,-758.49 2638.39,-765.9" />
|
||||
<polygon fill="black" stroke="black" points="1074.53,-954.48 1076.89,-965.19 1077.51,-958.49 1080.5,-962.5 1080.5,-962.5 1080.5,-962.5 1077.51,-958.49 1084.11,-959.81 1074.53,-954.48 1074.53,-954.48" />
|
||||
<ellipse fill="none" stroke="black" cx="1072.14" cy="-951.27" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="2633.61,-777.11 2628.06,-768.79 2629.72,-767.68 2635.27,-776 2633.61,-777.11" />
|
||||
<polyline fill="none" stroke="black" points="2630,-773.5 2634.16,-770.73 " />
|
||||
<polygon fill="black" stroke="black" points="2637.77,-774.33 2632.22,-766.01 2633.88,-764.9 2639.43,-773.22 2637.77,-774.33" />
|
||||
<polyline fill="none" stroke="black" points="2634.16,-770.73 2638.32,-767.95 " />
|
||||
<text text-anchor="start" x="1760.5" y="-873.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_billing_cancellation_domain_history</text>
|
||||
<polygon fill="black" stroke="black" points="2633.61,-775.11 2628.06,-766.79 2629.72,-765.68 2635.27,-774 2633.61,-775.11" />
|
||||
<polyline fill="none" stroke="black" points="2630,-771.5 2634.16,-768.73 " />
|
||||
<polygon fill="black" stroke="black" points="2637.77,-772.33 2632.22,-764.01 2633.88,-762.9 2639.43,-771.22 2637.77,-772.33" />
|
||||
<polyline fill="none" stroke="black" points="2634.16,-768.73 2638.32,-765.95 " />
|
||||
<text text-anchor="start" x="1760.5" y="-872.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_billing_cancellation_domain_history</text>
|
||||
</g> <!-- billingcancellation_6eedf614->domainhistory_a54cc226 -->
|
||||
<g id="edge30" class="edge">
|
||||
<title>
|
||||
billingcancellation_6eedf614:w->domainhistory_a54cc226:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M1071.29,-998.07C1069,-1016.69 1074.07,-1046.33 1081.5,-1054 1106.23,-1079.52 1365.77,-1063.82 1401,-1068.5 1409.12,-1069.58 1410.85,-1071.61 1419,-1072.5 1532.1,-1084.92 1561.28,-1075.99 1675,-1072.5 1957.62,-1063.83 2034.4,-1096.72 2310,-1033.5 2459.39,-999.23 2541.74,-1028.5 2629,-902.5 2634.55,-894.49 2639.64,-882.57 2638.14,-875.46" />
|
||||
<path fill="none" stroke="black" d="M1071.29,-998.07C1069,-1016.69 1074.07,-1046.33 1081.5,-1054 1106.23,-1079.52 1365.91,-1062.9 1401,-1068.5 1409.2,-1069.81 1410.77,-1072.38 1419,-1073.5 1531.74,-1088.87 1561.28,-1077.17 1675,-1073.5 1957.66,-1064.38 2034.54,-1096.54 2310,-1032.5 2459.45,-997.76 2541.81,-1026.76 2629,-900.5 2634.54,-892.48 2639.63,-880.56 2638.13,-873.46" />
|
||||
<polygon fill="black" stroke="black" points="1075.41,-991.11 1084.37,-984.79 1077.95,-986.8 1080.5,-982.5 1080.5,-982.5 1080.5,-982.5 1077.95,-986.8 1076.63,-980.21 1075.41,-991.11 1075.41,-991.11" />
|
||||
<ellipse fill="none" stroke="black" cx="1073.37" cy="-994.55" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="2627.85,-874.12 2633.76,-866.06 2635.37,-867.24 2629.47,-875.31 2627.85,-874.12" />
|
||||
<polyline fill="none" stroke="black" points="2630,-869.5 2634.03,-872.45 " />
|
||||
<polygon fill="black" stroke="black" points="2631.89,-877.08 2637.79,-869.01 2639.41,-870.19 2633.5,-878.26 2631.89,-877.08" />
|
||||
<polyline fill="none" stroke="black" points="2634.03,-872.45 2638.07,-875.41 " />
|
||||
<polygon fill="black" stroke="black" points="2627.85,-872.12 2633.76,-864.06 2635.37,-865.24 2629.47,-873.31 2627.85,-872.12" />
|
||||
<polyline fill="none" stroke="black" points="2630,-867.5 2634.03,-870.45 " />
|
||||
<polygon fill="black" stroke="black" points="2631.89,-875.08 2637.79,-867.01 2639.41,-868.19 2633.5,-876.26 2631.89,-875.08" />
|
||||
<polyline fill="none" stroke="black" points="2634.03,-870.45 2638.07,-873.41 " />
|
||||
<text text-anchor="start" x="1760.5" y="-1078.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_billing_cancellation_domain_history</text>
|
||||
</g> <!-- billingcancellation_6eedf614->billingrecurrence_5fa2cb01 -->
|
||||
<g id="edge8" class="edge">
|
||||
@@ -1059,27 +1059,27 @@ td.section {
|
||||
<title>
|
||||
billingrecurrence_5fa2cb01:w->domainhistory_a54cc226:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M446.69,-733C441.92,-710.35 448.28,-668.11 458.5,-658 507.72,-609.33 700.79,-656.99 770,-658 1172.35,-663.89 1272.99,-666.82 1675,-684.5 1887.16,-693.83 2480.98,-588.22 2629,-740.5 2636.03,-747.73 2640.8,-760.62 2638.33,-767.97" />
|
||||
<path fill="none" stroke="black" d="M446.69,-733C441.92,-710.35 448.28,-668.11 458.5,-658 507.72,-609.33 700.79,-656.99 770,-658 1172.35,-663.89 1272.98,-667.24 1675,-684.5 1887.14,-693.61 2480.84,-586.4 2629,-738.5 2636.04,-745.73 2640.81,-758.61 2638.33,-765.96" />
|
||||
<polygon fill="black" stroke="black" points="451.52,-739.48 453.89,-750.19 454.51,-743.49 457.5,-747.5 457.5,-747.5 457.5,-747.5 454.51,-743.49 461.11,-744.81 451.52,-739.48 451.52,-739.48" />
|
||||
<ellipse fill="none" stroke="black" cx="449.13" cy="-736.28" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="2633.6,-777.11 2628.07,-768.78 2629.73,-767.68 2635.27,-776 2633.6,-777.11" />
|
||||
<polyline fill="none" stroke="black" points="2630,-773.5 2634.16,-770.73 " />
|
||||
<polygon fill="black" stroke="black" points="2637.76,-774.34 2632.23,-766.01 2633.9,-764.91 2639.43,-773.24 2637.76,-774.34" />
|
||||
<polyline fill="none" stroke="black" points="2634.16,-770.73 2638.33,-767.97 " />
|
||||
<polygon fill="black" stroke="black" points="2633.6,-775.11 2628.07,-766.78 2629.73,-765.68 2635.27,-774 2633.6,-775.11" />
|
||||
<polyline fill="none" stroke="black" points="2630,-771.5 2634.16,-768.73 " />
|
||||
<polygon fill="black" stroke="black" points="2637.76,-772.34 2632.23,-764.01 2633.9,-762.91 2639.43,-771.24 2637.76,-772.34" />
|
||||
<polyline fill="none" stroke="black" points="2634.16,-768.73 2638.33,-765.97 " />
|
||||
<text text-anchor="start" x="1434.5" y="-688.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_billing_recurrence_domain_history</text>
|
||||
</g> <!-- billingrecurrence_5fa2cb01->domainhistory_a54cc226 -->
|
||||
<g id="edge36" class="edge">
|
||||
<title>
|
||||
billingrecurrence_5fa2cb01:w->domainhistory_a54cc226:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M448.24,-783.12C445.89,-801.8 450.9,-831.5 458.5,-839 557.08,-936.21 652.03,-911.45 770,-839 785.07,-829.74 774.03,-814.36 788,-803.5 889.4,-724.69 942.35,-754.58 1070,-740.5 1216.22,-724.37 1255.53,-718.59 1401,-740.5 1535.29,-760.73 1560.07,-802.73 1693,-830.5 1971.03,-888.58 2044.42,-886.47 2328,-902.5 2461.56,-910.05 2532.98,-995.65 2629,-902.5 2636.24,-895.48 2640.93,-882.51 2638.39,-875.1" />
|
||||
<path fill="none" stroke="black" d="M448.24,-783.12C445.89,-801.8 450.9,-831.5 458.5,-839 557.08,-936.21 652.03,-911.45 770,-839 785.07,-829.74 774.03,-814.36 788,-803.5 889.4,-724.69 942.35,-754.58 1070,-740.5 1216.22,-724.37 1255.46,-719.05 1401,-740.5 1535.09,-760.27 1560.23,-801.2 1693,-828.5 1971.21,-885.71 2044.42,-884.47 2328,-900.5 2461.56,-908.05 2532.98,-993.65 2629,-900.5 2636.24,-893.48 2640.93,-880.51 2638.39,-873.1" />
|
||||
<polygon fill="black" stroke="black" points="452.4,-776.1 461.37,-769.8 454.95,-771.8 457.5,-767.5 457.5,-767.5 457.5,-767.5 454.95,-771.8 453.63,-765.2 452.4,-776.1 452.4,-776.1" />
|
||||
<ellipse fill="none" stroke="black" cx="450.36" cy="-779.54" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="2628.06,-874.21 2633.61,-865.89 2635.27,-867 2629.72,-875.32 2628.06,-874.21" />
|
||||
<polyline fill="none" stroke="black" points="2630,-869.5 2634.16,-872.27 " />
|
||||
<polygon fill="black" stroke="black" points="2632.22,-876.99 2637.77,-868.67 2639.43,-869.78 2633.88,-878.1 2632.22,-876.99" />
|
||||
<polyline fill="none" stroke="black" points="2634.16,-872.27 2638.32,-875.05 " />
|
||||
<text text-anchor="start" x="1434.5" y="-830.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_billing_recurrence_domain_history</text>
|
||||
<polygon fill="black" stroke="black" points="2628.06,-872.21 2633.61,-863.89 2635.27,-865 2629.72,-873.32 2628.06,-872.21" />
|
||||
<polyline fill="none" stroke="black" points="2630,-867.5 2634.16,-870.27 " />
|
||||
<polygon fill="black" stroke="black" points="2632.22,-874.99 2637.77,-866.67 2639.43,-867.78 2633.88,-876.1 2632.22,-874.99" />
|
||||
<polyline fill="none" stroke="black" points="2634.16,-870.27 2638.32,-873.05 " />
|
||||
<text text-anchor="start" x="1434.5" y="-828.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_billing_recurrence_domain_history</text>
|
||||
</g> <!-- billingrecurrence_5fa2cb01->registrar_6e1503e3 -->
|
||||
<g id="edge55" class="edge">
|
||||
<title>
|
||||
@@ -1440,26 +1440,26 @@ td.section {
|
||||
<title>
|
||||
pollmessage_614a523e:w->domainhistory_a54cc226:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M3635.14,-1709.39C3618.47,-1694.46 3640.72,-1649.84 3626,-1615.5 3558.49,-1458.01 3475.42,-1450.27 3425,-1286.5 3412.95,-1247.37 3435.42,-947.96 3407,-918.5 3341.5,-850.6 3074.81,-908.05 2984,-882.5 2975.39,-880.08 2974.6,-875.94 2966,-873.5 2899.46,-854.59 2710.76,-887.75 2656,-845.5 2632.43,-827.31 2656.25,-785.83 2639.78,-775.74" />
|
||||
<path fill="none" stroke="black" d="M3635.14,-1709.39C3618.47,-1694.46 3640.72,-1649.84 3626,-1615.5 3558.49,-1458.01 3475.42,-1450.27 3425,-1286.5 3412.95,-1247.37 3435.42,-947.96 3407,-918.5 3341.5,-850.6 3074.81,-908.05 2984,-882.5 2975.39,-880.08 2974.6,-875.94 2966,-873.5 2899.46,-854.59 2710.58,-887.99 2656,-845.5 2631.93,-826.76 2656.77,-784.16 2640,-773.8" />
|
||||
<polygon fill="black" stroke="black" points="3642.91,-1711.67 3651.23,-1718.82 3647.7,-1713.09 3652.5,-1714.5 3652.5,-1714.5 3652.5,-1714.5 3647.7,-1713.09 3653.77,-1710.18 3642.91,-1711.67 3642.91,-1711.67" />
|
||||
<ellipse fill="none" stroke="black" cx="3639.07" cy="-1710.54" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="2629.86,-778.6 2632.09,-768.85 2634.04,-769.3 2631.81,-779.04 2629.86,-778.6" />
|
||||
<polyline fill="none" stroke="black" points="2630,-773.5 2634.87,-774.62 " />
|
||||
<polygon fill="black" stroke="black" points="2634.73,-779.71 2636.97,-769.97 2638.91,-770.41 2636.68,-780.16 2634.73,-779.71" />
|
||||
<polyline fill="none" stroke="black" points="2634.87,-774.62 2639.75,-775.73 " />
|
||||
<polygon fill="black" stroke="black" points="2629.85,-776.6 2632.1,-766.85 2634.05,-767.3 2631.8,-777.05 2629.85,-776.6" />
|
||||
<polyline fill="none" stroke="black" points="2630,-771.5 2634.87,-772.62 " />
|
||||
<polygon fill="black" stroke="black" points="2634.73,-777.72 2636.97,-767.97 2638.92,-768.42 2636.67,-778.17 2634.73,-777.72" />
|
||||
<polyline fill="none" stroke="black" points="2634.87,-772.62 2639.75,-773.74 " />
|
||||
<text text-anchor="start" x="3094.5" y="-922.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_poll_message_domain_history</text>
|
||||
</g> <!-- pollmessage_614a523e->domainhistory_a54cc226 -->
|
||||
<g id="edge46" class="edge">
|
||||
<title>
|
||||
pollmessage_614a523e:w->domainhistory_a54cc226:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M3636.21,-1686.03C3629.34,-1670.28 3644.54,-1636.18 3626,-1615.5 3410.32,-1374.87 3260.46,-1443.59 2966,-1310.5 2828.74,-1248.46 2743.52,-1296.1 2656,-1173.5 2638.11,-1148.44 2659.23,-918.15 2637.87,-876.08" />
|
||||
<path fill="none" stroke="black" d="M3636.21,-1686.03C3629.34,-1670.28 3644.54,-1636.18 3626,-1615.5 3410.32,-1374.87 3260.28,-1443.99 2966,-1310.5 2828.66,-1248.2 2743.44,-1295.37 2656,-1172.5 2638.05,-1147.28 2659.41,-915.31 2637.75,-873.83" />
|
||||
<polygon fill="black" stroke="black" points="3643.63,-1689.89 3650.42,-1698.49 3648.06,-1692.19 3652.5,-1694.5 3652.5,-1694.5 3652.5,-1694.5 3648.06,-1692.19 3654.58,-1690.51 3643.63,-1689.89 3643.63,-1689.89" />
|
||||
<ellipse fill="none" stroke="black" cx="3640.08" cy="-1688.04" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="2627.56,-873.98 2633.98,-866.31 2635.51,-867.59 2629.09,-875.26 2627.56,-873.98" />
|
||||
<polyline fill="none" stroke="black" points="2630,-869.5 2633.83,-872.71 " />
|
||||
<polygon fill="black" stroke="black" points="2631.39,-877.19 2637.81,-869.52 2639.34,-870.8 2632.93,-878.47 2631.39,-877.19" />
|
||||
<polyline fill="none" stroke="black" points="2633.83,-872.71 2637.67,-875.92 " />
|
||||
<polygon fill="black" stroke="black" points="2627.61,-872 2633.94,-864.26 2635.49,-865.53 2629.16,-873.27 2627.61,-872" />
|
||||
<polyline fill="none" stroke="black" points="2630,-867.5 2633.87,-870.66 " />
|
||||
<polygon fill="black" stroke="black" points="2631.48,-875.17 2637.81,-867.42 2639.36,-868.69 2633.03,-876.43 2631.48,-875.17" />
|
||||
<polyline fill="none" stroke="black" points="2633.87,-870.66 2637.74,-873.83 " />
|
||||
<text text-anchor="start" x="3094.5" y="-1454.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_poll_message_domain_history</text>
|
||||
</g> <!-- pollmessage_614a523e->contact_8de8cb16 -->
|
||||
<g id="edge20" class="edge">
|
||||
@@ -1625,20 +1625,20 @@ td.section {
|
||||
<title>
|
||||
pollmessage_614a523e:w->registrar_6e1503e3:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M3634.24,-1616.43C3631.94,-1616.06 3629.33,-1615.73 3626,-1615.5 3333.26,-1595.64 3259.39,-1603.83 2966,-1600.5 2828.23,-1598.93 2778.63,-1537.69 2656,-1600.5 2643.81,-1606.74 2649.95,-1618.82 2638,-1625.5 2529.1,-1686.41 2191.46,-1614.57 2078,-1666.5 2067.71,-1671.21 2070.13,-1679.47 2060,-1684.5 1957.13,-1735.55 1662.84,-1754.5 1548,-1754.5 1548,-1754.5 1548,-1754.5 608.5,-1754.5 524.44,-1754.5 291.93,-1788.41 231,-1730.5 197.82,-1698.96 246.35,-1536.9 215.23,-1511.78" />
|
||||
<path fill="none" stroke="black" d="M3634.24,-1616.43C3631.94,-1616.06 3629.33,-1615.73 3626,-1615.5 3333.26,-1595.64 3259.39,-1603.83 2966,-1600.5 2828.23,-1598.93 2778.63,-1537.69 2656,-1600.5 2643.81,-1606.74 2649.99,-1618.88 2638,-1625.5 2528.85,-1685.78 2187.73,-1601.29 2078,-1660.5 2066.27,-1666.83 2071.49,-1677.74 2060,-1684.5 1961.01,-1742.71 1662.84,-1754.5 1548,-1754.5 1548,-1754.5 1548,-1754.5 608.5,-1754.5 524.44,-1754.5 291.93,-1788.41 231,-1730.5 197.82,-1698.96 246.35,-1536.9 215.23,-1511.78" />
|
||||
<polygon fill="black" stroke="black" points="3642.56,-1617.37 3651.99,-1622.97 3647.53,-1617.94 3652.5,-1618.5 3652.5,-1618.5 3652.5,-1618.5 3647.53,-1617.94 3653.01,-1614.03 3642.56,-1617.37 3642.56,-1617.37" />
|
||||
<ellipse fill="none" stroke="black" cx="3638.59" cy="-1616.92" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="204.85,-1513.56 208.04,-1504.08 209.94,-1504.72 206.75,-1514.2 204.85,-1513.56" />
|
||||
<polyline fill="none" stroke="black" points="205.5,-1508.5 210.24,-1510.1 " />
|
||||
<polygon fill="black" stroke="black" points="209.59,-1515.15 212.78,-1505.68 214.68,-1506.32 211.49,-1515.79 209.59,-1515.15" />
|
||||
<polyline fill="none" stroke="black" points="210.24,-1510.1 214.98,-1511.69 " />
|
||||
<text text-anchor="start" x="1704" y="-1753.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_poll_message_transfer_response_gaining_registrar_id</text>
|
||||
<text text-anchor="start" x="1704" y="-1754.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_poll_message_transfer_response_gaining_registrar_id</text>
|
||||
</g> <!-- pollmessage_614a523e->registrar_6e1503e3 -->
|
||||
<g id="edge75" class="edge">
|
||||
<title>
|
||||
pollmessage_614a523e:w->registrar_6e1503e3:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M3634.32,-1598.69C3526.73,-1588.75 3522.25,-1490.05 3407,-1459.5 3225.28,-1411.33 3132.37,-1344.05 2984,-1459.5 2958.31,-1479.49 2990.46,-1509.02 2966,-1530.5 2963.62,-1532.59 2063.15,-1638.2 2060,-1638.5 1978.6,-1646.34 1764.37,-1625.57 1693,-1665.5 1681.05,-1672.19 1687.05,-1683.99 1675,-1690.5 1567.75,-1748.43 1522.87,-1699.83 1401,-1702.5 1271.02,-1705.34 328.42,-1772.6 231,-1686.5 203.98,-1662.62 237.5,-1536.9 214.94,-1512.58" />
|
||||
<path fill="none" stroke="black" d="M3634.32,-1598.69C3526.73,-1588.75 3522.25,-1490.05 3407,-1459.5 3225.28,-1411.33 3132.18,-1343.8 2984,-1459.5 2958,-1479.8 2990.78,-1509.73 2966,-1531.5 2963.67,-1533.55 2081.06,-1633.98 2078,-1634.5 2069.92,-1635.86 2068.11,-1637.31 2060,-1638.5 1979.09,-1650.4 1764.37,-1625.57 1693,-1665.5 1681.05,-1672.19 1687.05,-1683.99 1675,-1690.5 1567.75,-1748.43 1522.87,-1699.83 1401,-1702.5 1271.02,-1705.34 328.42,-1772.6 231,-1686.5 203.98,-1662.62 237.5,-1536.9 214.94,-1512.58" />
|
||||
<polygon fill="black" stroke="black" points="3642.51,-1599.05 3652.3,-1604 3647.5,-1599.28 3652.5,-1599.5 3652.5,-1599.5 3652.5,-1599.5 3647.5,-1599.28 3652.7,-1595 3642.51,-1599.05 3642.51,-1599.05" />
|
||||
<ellipse fill="none" stroke="black" cx="3638.51" cy="-1598.88" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="204.44,-1513.49 208.4,-1504.31 210.24,-1505.1 206.27,-1514.28 204.44,-1513.49" />
|
||||
@@ -1768,14 +1768,14 @@ td.section {
|
||||
<title>
|
||||
host_f21b78de:w->domain_6c51cffa:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M2331.47,-1696.28C2272.5,-1679.09 2090.96,-1615.01 2078,-1610.5 2064.56,-1605.83 2059.74,-1599.91 2049.58,-1597.55" />
|
||||
<polygon fill="black" stroke="black" points="2339.28,-1698.16 2347.95,-1704.88 2344.14,-1699.33 2349,-1700.5 2349,-1700.5 2349,-1700.5 2344.14,-1699.33 2350.05,-1696.12 2339.28,-1698.16 2339.28,-1698.16" />
|
||||
<ellipse fill="none" stroke="black" cx="2335.39" cy="-1697.23" rx="4" ry="4" />
|
||||
<path fill="none" stroke="black" d="M2330.78,-1700.15C2219.44,-1695.7 2191.9,-1650.11 2078,-1610.5 2064.56,-1605.83 2059.74,-1599.91 2049.58,-1597.55" />
|
||||
<polygon fill="black" stroke="black" points="2339,-1700.31 2348.91,-1705 2344,-1700.4 2349,-1700.5 2349,-1700.5 2349,-1700.5 2344,-1700.4 2349.09,-1696 2339,-1700.31 2339,-1700.31" />
|
||||
<ellipse fill="none" stroke="black" cx="2335" cy="-1700.23" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="2039.98,-1601.58 2041.01,-1591.63 2043,-1591.84 2041.97,-1601.78 2039.98,-1601.58" />
|
||||
<polyline fill="none" stroke="black" points="2039.5,-1596.5 2044.47,-1597.02 " />
|
||||
<polygon fill="black" stroke="black" points="2044.95,-1602.09 2045.98,-1592.15 2047.97,-1592.35 2046.94,-1602.3 2044.95,-1602.09" />
|
||||
<polyline fill="none" stroke="black" points="2044.47,-1597.02 2049.45,-1597.53 " />
|
||||
<text text-anchor="start" x="2100.5" y="-1692.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_host_superordinate_domain</text>
|
||||
<text text-anchor="start" x="2100.5" y="-1703.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk_host_superordinate_domain</text>
|
||||
</g> <!-- host_f21b78de->registrar_6e1503e3 -->
|
||||
<g id="edge69" class="edge">
|
||||
<title>
|
||||
@@ -1839,26 +1839,26 @@ td.section {
|
||||
<title>
|
||||
domaindsdatahistory_995b060d:w->domainhistory_a54cc226:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M3037.23,-801.4C3015.74,-800.86 3002.54,-797.58 2984,-778.5 2964,-757.92 2988.94,-733.73 2966,-716.5 2938.46,-695.82 2684.97,-697.87 2656,-716.5 2636.42,-729.09 2650.86,-760.46 2639.87,-770.42" />
|
||||
<path fill="none" stroke="black" d="M3037.23,-801.4C3015.74,-800.86 3002.54,-797.58 2984,-778.5 2964,-757.92 2988.94,-733.73 2966,-716.5 2938.46,-695.82 2685.1,-698.07 2656,-716.5 2636.91,-728.59 2650.46,-758.9 2639.63,-768.52" />
|
||||
<polygon fill="black" stroke="black" points="3045.5,-801.45 3055.48,-806 3050.5,-801.47 3055.5,-801.5 3055.5,-801.5 3055.5,-801.5 3050.5,-801.47 3055.52,-797 3045.5,-801.45 3045.5,-801.45" />
|
||||
<ellipse fill="none" stroke="black" cx="3041.5" cy="-801.42" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="2632.45,-777.97 2629.46,-768.43 2631.37,-767.83 2634.35,-777.38 2632.45,-777.97" />
|
||||
<polyline fill="none" stroke="black" points="2630,-773.5 2634.77,-772.01 " />
|
||||
<polygon fill="black" stroke="black" points="2637.22,-776.48 2634.24,-766.94 2636.14,-766.34 2639.13,-775.89 2637.22,-776.48" />
|
||||
<polyline fill="none" stroke="black" points="2634.77,-772.01 2639.54,-770.52 " />
|
||||
<polygon fill="black" stroke="black" points="2632.43,-775.98 2629.48,-766.43 2631.39,-765.84 2634.34,-775.39 2632.43,-775.98" />
|
||||
<polyline fill="none" stroke="black" points="2630,-771.5 2634.78,-770.02 " />
|
||||
<polygon fill="black" stroke="black" points="2637.21,-774.5 2634.25,-764.95 2636.16,-764.36 2639.12,-773.91 2637.21,-774.5" />
|
||||
<polyline fill="none" stroke="black" points="2634.78,-770.02 2639.55,-768.54 " />
|
||||
<text text-anchor="start" x="2726.5" y="-720.3" font-family="Helvetica,sans-Serif" font-size="14.00">fko4ilgyyfnvppbpuivus565i0j</text>
|
||||
</g> <!-- domaindsdatahistory_995b060d->domainhistory_a54cc226 -->
|
||||
<g id="edge38" class="edge">
|
||||
<title>
|
||||
domaindsdatahistory_995b060d:w->domainhistory_a54cc226:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M3037.23,-820.14C2938.18,-816.69 2728.91,-790.3 2656,-830.5 2641.75,-838.36 2646.61,-857.74 2639.49,-865.85" />
|
||||
<polygon fill="black" stroke="black" points="3045.5,-820.3 3055.41,-825 3050.5,-820.4 3055.5,-820.5 3055.5,-820.5 3055.5,-820.5 3050.5,-820.4 3055.59,-816 3045.5,-820.3 3045.5,-820.3" />
|
||||
<ellipse fill="none" stroke="black" cx="3041.5" cy="-820.22" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="2632.73,-873.81 2629.14,-864.47 2631,-863.76 2634.6,-873.09 2632.73,-873.81" />
|
||||
<polyline fill="none" stroke="black" points="2630,-869.5 2634.67,-867.7 " />
|
||||
<polygon fill="black" stroke="black" points="2637.4,-872.01 2633.8,-862.68 2635.67,-861.96 2639.26,-871.29 2637.4,-872.01" />
|
||||
<polyline fill="none" stroke="black" points="2634.67,-867.7 2639.33,-865.91 " />
|
||||
<path fill="none" stroke="black" d="M3037.24,-820.15C2938.25,-816.8 2729.39,-791.2 2656,-830.5 2642.43,-837.76 2646.18,-855.59 2639.66,-863.55" />
|
||||
<polygon fill="black" stroke="black" points="3045.5,-820.31 3055.41,-825 3050.5,-820.4 3055.5,-820.5 3055.5,-820.5 3055.5,-820.5 3050.5,-820.4 3055.59,-816 3045.5,-820.31 3045.5,-820.31" />
|
||||
<ellipse fill="none" stroke="black" cx="3041.5" cy="-820.23" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="2632.82,-871.75 2629.03,-862.49 2630.89,-861.74 2634.67,-870.99 2632.82,-871.75" />
|
||||
<polyline fill="none" stroke="black" points="2630,-867.5 2634.63,-865.61 " />
|
||||
<polygon fill="black" stroke="black" points="2637.45,-869.86 2633.66,-860.6 2635.52,-859.85 2639.3,-869.1 2637.45,-869.86" />
|
||||
<polyline fill="none" stroke="black" points="2634.63,-865.61 2639.26,-863.72 " />
|
||||
<text text-anchor="start" x="2726.5" y="-834.3" font-family="Helvetica,sans-Serif" font-size="14.00">fko4ilgyyfnvppbpuivus565i0j</text>
|
||||
</g> <!-- domainhistoryhost_9f3f23ee -->
|
||||
<g id="node24" class="node">
|
||||
@@ -1884,26 +1884,26 @@ td.section {
|
||||
<title>
|
||||
domainhistoryhost_9f3f23ee:w->domainhistory_a54cc226:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M3027.22,-593.16C2929.15,-590.01 2716.2,-566.91 2656,-621.5 2633.49,-641.91 2657.4,-745.64 2639.22,-768.88" />
|
||||
<path fill="none" stroke="black" d="M3027.23,-593.17C2929.16,-590.02 2716.26,-566.97 2656,-621.5 2608.67,-664.32 2687.71,-759.84 2640.02,-770.52" />
|
||||
<polygon fill="black" stroke="black" points="3035.5,-593.32 3045.42,-598 3040.5,-593.41 3045.5,-593.5 3045.5,-593.5 3045.5,-593.5 3040.5,-593.41 3045.58,-589 3035.5,-593.32 3035.5,-593.32" />
|
||||
<ellipse fill="none" stroke="black" cx="3031.5" cy="-593.24" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="2633.14,-777.52 2628.65,-768.58 2630.44,-767.69 2634.92,-776.62 2633.14,-777.52" />
|
||||
<polyline fill="none" stroke="black" points="2630,-773.5 2634.47,-771.26 " />
|
||||
<polygon fill="black" stroke="black" points="2637.61,-775.28 2633.12,-766.34 2634.91,-765.44 2639.39,-774.38 2637.61,-775.28" />
|
||||
<polyline fill="none" stroke="black" points="2634.47,-771.26 2638.94,-769.02 " />
|
||||
<polygon fill="black" stroke="black" points="2631.48,-776.38 2630.51,-766.43 2632.5,-766.23 2633.47,-776.19 2631.48,-776.38" />
|
||||
<polyline fill="none" stroke="black" points="2630,-771.5 2634.98,-771.01 " />
|
||||
<polygon fill="black" stroke="black" points="2636.46,-775.89 2635.49,-765.94 2637.48,-765.75 2638.45,-775.7 2636.46,-775.89" />
|
||||
<polyline fill="none" stroke="black" points="2634.98,-771.01 2639.95,-770.53 " />
|
||||
<text text-anchor="start" x="2716.5" y="-625.3" font-family="Helvetica,sans-Serif" font-size="14.00">fka9woh3hu8gx5x0vly6bai327n</text>
|
||||
</g> <!-- domainhistoryhost_9f3f23ee->domainhistory_a54cc226 -->
|
||||
<g id="edge40" class="edge">
|
||||
<title>
|
||||
domainhistoryhost_9f3f23ee:w->domainhistory_a54cc226:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M3027.48,-634.52C3008.25,-639.5 2999.57,-653.53 2984,-674.5 2968.16,-695.83 2986.94,-715.15 2966,-731.5 2911.61,-773.98 2708.41,-705.59 2656,-750.5 2617.94,-783.11 2674.47,-857.33 2640.11,-868.17" />
|
||||
<path fill="none" stroke="black" d="M3027.48,-634.52C3008.25,-639.5 2999.57,-653.53 2984,-674.5 2968.16,-695.83 2986.94,-715.15 2966,-731.5 2911.61,-773.98 2708.49,-705.69 2656,-750.5 2618.49,-782.52 2673.8,-855.53 2639.95,-866.19" />
|
||||
<polygon fill="black" stroke="black" points="3035.56,-633.61 3046,-636.97 3040.53,-633.06 3045.5,-632.5 3045.5,-632.5 3045.5,-632.5 3040.53,-633.06 3045,-628.03 3035.56,-633.61 3035.56,-633.61" />
|
||||
<ellipse fill="none" stroke="black" cx="3031.59" cy="-634.06" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="2631.64,-874.33 2630.34,-864.41 2632.32,-864.15 2633.63,-874.07 2631.64,-874.33" />
|
||||
<polyline fill="none" stroke="black" points="2630,-869.5 2634.96,-868.85 " />
|
||||
<polygon fill="black" stroke="black" points="2636.6,-873.67 2635.3,-863.76 2637.28,-863.5 2638.58,-873.41 2636.6,-873.67" />
|
||||
<polyline fill="none" stroke="black" points="2634.96,-868.85 2639.91,-868.2 " />
|
||||
<polygon fill="black" stroke="black" points="2631.64,-872.33 2630.34,-862.41 2632.32,-862.15 2633.63,-872.07 2631.64,-872.33" />
|
||||
<polyline fill="none" stroke="black" points="2630,-867.5 2634.96,-866.85 " />
|
||||
<polygon fill="black" stroke="black" points="2636.6,-871.68 2635.3,-861.76 2637.28,-861.5 2638.58,-871.41 2636.6,-871.68" />
|
||||
<polyline fill="none" stroke="black" points="2634.96,-866.85 2639.91,-866.2 " />
|
||||
<text text-anchor="start" x="2716.5" y="-754.3" font-family="Helvetica,sans-Serif" font-size="14.00">fka9woh3hu8gx5x0vly6bai327n</text>
|
||||
</g> <!-- domaintransactionrecord_6e77ff61 -->
|
||||
<g id="node25" class="node">
|
||||
@@ -1934,33 +1934,33 @@ td.section {
|
||||
<title>
|
||||
domaintransactionrecord_6e77ff61:w->domainhistory_a54cc226:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M3005.2,-969.73C2995.87,-961.16 2994.42,-944.37 2984,-928.5 2974.4,-913.87 2980.58,-903.16 2966,-893.5 2908.41,-855.36 2709.21,-914.55 2656,-870.5 2624.84,-844.71 2665.46,-786 2640.13,-775.22" />
|
||||
<path fill="none" stroke="black" d="M3005.2,-969.73C2995.87,-961.16 2994.42,-944.37 2984,-928.5 2974.4,-913.87 2980.58,-903.16 2966,-893.5 2908.41,-855.36 2709.1,-914.68 2656,-870.5 2624.17,-844.02 2666.43,-783.73 2639.98,-773.11" />
|
||||
<polygon fill="black" stroke="black" points="3013.01,-972.34 3021.08,-979.77 3017.76,-973.92 3022.5,-975.5 3022.5,-975.5 3022.5,-975.5 3017.76,-973.92 3023.92,-971.23 3013.01,-972.34 3013.01,-972.34" />
|
||||
<ellipse fill="none" stroke="black" cx="3009.22" cy="-971.07" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="2630.15,-778.6 2631.82,-768.74 2633.79,-769.07 2632.12,-778.93 2630.15,-778.6" />
|
||||
<polyline fill="none" stroke="black" points="2630,-773.5 2634.93,-774.34 " />
|
||||
<polygon fill="black" stroke="black" points="2635.08,-779.43 2636.75,-769.57 2638.72,-769.91 2637.05,-779.77 2635.08,-779.43" />
|
||||
<polyline fill="none" stroke="black" points="2634.93,-774.34 2639.86,-775.17 " />
|
||||
<polygon fill="black" stroke="black" points="2630.19,-776.6 2631.78,-766.72 2633.76,-767.04 2632.16,-776.91 2630.19,-776.6" />
|
||||
<polyline fill="none" stroke="black" points="2630,-771.5 2634.94,-772.3 " />
|
||||
<polygon fill="black" stroke="black" points="2635.13,-777.39 2636.72,-767.52 2638.7,-767.84 2637.1,-777.71 2635.13,-777.39" />
|
||||
<polyline fill="none" stroke="black" points="2634.94,-772.3 2639.87,-773.1 " />
|
||||
<text text-anchor="start" x="2721" y="-897.3" font-family="Helvetica,sans-Serif" font-size="14.00">fkcjqe54u72kha71vkibvxhjye7</text>
|
||||
</g> <!-- domaintransactionrecord_6e77ff61->domainhistory_a54cc226 -->
|
||||
<g id="edge42" class="edge">
|
||||
<title>
|
||||
domaintransactionrecord_6e77ff61:w->domainhistory_a54cc226:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M3004.86,-960.38C2992,-966.91 2986.04,-979.81 2966,-984.5 2932.46,-992.35 2682.91,-1006 2656,-984.5 2618.26,-954.34 2672.54,-882.05 2640.2,-870.94" />
|
||||
<path fill="none" stroke="black" d="M3004.86,-960.38C2992,-966.91 2986.04,-979.81 2966,-984.5 2932.46,-992.35 2682.87,-1006.05 2656,-984.5 2617.53,-953.64 2673.66,-879.64 2639.94,-868.83" />
|
||||
<polygon fill="black" stroke="black" points="3012.73,-958.65 3023.47,-960.89 3017.62,-957.57 3022.5,-956.5 3022.5,-956.5 3022.5,-956.5 3017.62,-957.57 3021.53,-952.11 3012.73,-958.65 3012.73,-958.65" />
|
||||
<ellipse fill="none" stroke="black" cx="3008.83" cy="-959.51" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="2630.29,-874.59 2631.69,-864.69 2633.67,-864.97 2632.27,-874.87 2630.29,-874.59" />
|
||||
<polyline fill="none" stroke="black" points="2630,-869.5 2634.95,-870.2 " />
|
||||
<polygon fill="black" stroke="black" points="2635.24,-875.29 2636.64,-865.39 2638.62,-865.67 2637.22,-875.57 2635.24,-875.29" />
|
||||
<polyline fill="none" stroke="black" points="2634.95,-870.2 2639.9,-870.9 " />
|
||||
<polygon fill="black" stroke="black" points="2630.33,-872.59 2631.65,-862.68 2633.64,-862.94 2632.31,-872.85 2630.33,-872.59" />
|
||||
<polyline fill="none" stroke="black" points="2630,-867.5 2634.96,-868.16 " />
|
||||
<polygon fill="black" stroke="black" points="2635.28,-873.25 2636.61,-863.34 2638.59,-863.6 2637.27,-873.52 2635.28,-873.25" />
|
||||
<polyline fill="none" stroke="black" points="2634.96,-868.16 2639.91,-868.82 " />
|
||||
<text text-anchor="start" x="2721" y="-1000.3" font-family="Helvetica,sans-Serif" font-size="14.00">fkcjqe54u72kha71vkibvxhjye7</text>
|
||||
</g> <!-- domaintransactionrecord_6e77ff61->tld_f1fa57e2 -->
|
||||
<g id="edge84" class="edge">
|
||||
<title>
|
||||
domaintransactionrecord_6e77ff61:w->tld_f1fa57e2:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M3005,-999.82C2987.94,-1013.55 2994.77,-1050.11 2966,-1064.5 2877.7,-1108.67 2176.49,-1089.6 2078,-1096.5 1898.36,-1109.08 1854.13,-1119.97 1675,-1138.5 1518.23,-1154.71 1477.31,-1174.62 1324.71,-1175.47" />
|
||||
<path fill="none" stroke="black" d="M3005,-999.82C2987.94,-1013.55 2994.77,-1050.11 2966,-1064.5 2877.7,-1108.67 2176.48,-1089.48 2078,-1096.5 1898.33,-1109.31 1854.17,-1120.99 1675,-1139.5 1518.27,-1155.69 1477.26,-1174.67 1324.71,-1175.47" />
|
||||
<polygon fill="black" stroke="black" points="3012.93,-997.41 3023.81,-998.81 3017.72,-995.95 3022.5,-994.5 3022.5,-994.5 3022.5,-994.5 3017.72,-995.95 3021.19,-990.19 3012.93,-997.41 3012.93,-997.41" />
|
||||
<ellipse fill="none" stroke="black" cx="3009.11" cy="-998.57" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="1315.51,-1180.5 1315.49,-1170.5 1317.49,-1170.49 1317.51,-1180.49 1315.51,-1180.5" />
|
||||
@@ -1992,27 +1992,27 @@ td.section {
|
||||
<title>
|
||||
graceperiodhistory_40ccc1f1:w->domainhistory_a54cc226:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M3025.59,-714.1C3003.62,-707.57 2995.8,-689.58 2966,-683.5 2831,-655.96 2766.12,-600.69 2656,-683.5 2626.1,-705.98 2662.55,-760.71 2640.06,-771.6" />
|
||||
<path fill="none" stroke="black" d="M3025.59,-714.1C3003.62,-707.57 2995.8,-689.58 2966,-683.5 2831,-655.96 2766.37,-601.03 2656,-683.5 2626.65,-705.43 2661.97,-758.99 2639.87,-769.64" />
|
||||
<polygon fill="black" stroke="black" points="3033.59,-715.17 3042.9,-720.96 3038.54,-715.83 3043.5,-716.5 3043.5,-716.5 3043.5,-716.5 3038.54,-715.83 3044.1,-712.04 3033.59,-715.17 3033.59,-715.17" />
|
||||
<ellipse fill="none" stroke="black" cx="3029.62" cy="-714.64" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="2631.91,-778.23 2630.05,-768.4 2632.02,-768.03 2633.88,-777.86 2631.91,-778.23" />
|
||||
<polyline fill="none" stroke="black" points="2630,-773.5 2634.91,-772.57 " />
|
||||
<polygon fill="black" stroke="black" points="2636.82,-777.3 2634.97,-767.47 2636.93,-767.1 2638.79,-776.93 2636.82,-777.3" />
|
||||
<polyline fill="none" stroke="black" points="2634.91,-772.57 2639.83,-771.64 " />
|
||||
<polygon fill="black" stroke="black" points="2631.91,-776.23 2630.06,-766.4 2632.02,-766.03 2633.87,-775.86 2631.91,-776.23" />
|
||||
<polyline fill="none" stroke="black" points="2630,-771.5 2634.91,-770.57 " />
|
||||
<polygon fill="black" stroke="black" points="2636.82,-775.3 2634.97,-765.48 2636.94,-765.11 2638.79,-774.93 2636.82,-775.3" />
|
||||
<polyline fill="none" stroke="black" points="2634.91,-770.57 2639.83,-769.65 " />
|
||||
<text text-anchor="start" x="2717" y="-687.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk7w3cx8d55q8bln80e716tr7b8</text>
|
||||
</g> <!-- graceperiodhistory_40ccc1f1->domainhistory_a54cc226 -->
|
||||
<g id="edge44" class="edge">
|
||||
<title>
|
||||
graceperiodhistory_40ccc1f1:w->domainhistory_a54cc226:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M3025.76,-700.91C2999.06,-712.97 3002.6,-753.74 2966,-769.5 2902.59,-796.8 2710.51,-747.15 2656,-789.5 2629.82,-809.84 2659.02,-857.01 2639.91,-867.44" />
|
||||
<polygon fill="black" stroke="black" points="3033.68,-699.39 3044.35,-701.92 3038.59,-698.44 3043.5,-697.5 3043.5,-697.5 3043.5,-697.5 3038.59,-698.44 3042.65,-693.08 3033.68,-699.39 3033.68,-699.39" />
|
||||
<path fill="none" stroke="black" d="M3025.76,-700.9C2999.05,-712.95 3002.58,-753.68 2966,-769.5 2902.62,-796.9 2710.7,-748.36 2656,-790.5 2630.74,-809.96 2657.97,-855.07 2639.84,-865.38" />
|
||||
<polygon fill="black" stroke="black" points="3033.68,-699.38 3044.35,-701.92 3038.59,-698.44 3043.5,-697.5 3043.5,-697.5 3043.5,-697.5 3038.59,-698.44 3042.65,-693.08 3033.68,-699.38 3033.68,-699.38" />
|
||||
<ellipse fill="none" stroke="black" cx="3029.75" cy="-700.14" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="2632,-874.19 2629.96,-864.4 2631.92,-863.99 2633.96,-873.78 2632,-874.19" />
|
||||
<polyline fill="none" stroke="black" points="2630,-869.5 2634.89,-868.48 " />
|
||||
<polygon fill="black" stroke="black" points="2636.89,-873.17 2634.85,-863.38 2636.81,-862.97 2638.85,-872.76 2636.89,-873.17" />
|
||||
<polyline fill="none" stroke="black" points="2634.89,-868.48 2639.79,-867.46 " />
|
||||
<text text-anchor="start" x="2717" y="-793.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk7w3cx8d55q8bln80e716tr7b8</text>
|
||||
<polygon fill="black" stroke="black" points="2632.03,-872.18 2629.92,-862.4 2631.88,-861.98 2633.99,-871.76 2632.03,-872.18" />
|
||||
<polyline fill="none" stroke="black" points="2630,-867.5 2634.89,-866.45 " />
|
||||
<polygon fill="black" stroke="black" points="2636.92,-871.12 2634.81,-861.35 2636.77,-860.93 2638.87,-870.7 2636.92,-871.12" />
|
||||
<polyline fill="none" stroke="black" points="2634.89,-866.45 2639.78,-865.39 " />
|
||||
<text text-anchor="start" x="2717" y="-794.3" font-family="Helvetica,sans-Serif" font-size="14.00">fk7w3cx8d55q8bln80e716tr7b8</text>
|
||||
</g> <!-- featureflag_3ee43a78 -->
|
||||
<g id="node27" class="node">
|
||||
<title>
|
||||
@@ -2157,28 +2157,25 @@ td.section {
|
||||
<title>
|
||||
registrarpoc_ab47054d
|
||||
</title>
|
||||
<polygon fill="#e9c2f2" stroke="transparent" points="499.5,-459.5 499.5,-478.5 645.5,-478.5 645.5,-459.5 499.5,-459.5" />
|
||||
<text text-anchor="start" x="501.5" y="-466.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."RegistrarPoc"</text>
|
||||
<polygon fill="#e9c2f2" stroke="transparent" points="645.5,-459.5 645.5,-478.5 719.5,-478.5 719.5,-459.5 645.5,-459.5" />
|
||||
<text text-anchor="start" x="680.5" y="-465.3" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
|
||||
<text text-anchor="start" x="501.5" y="-447.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">email_address</text>
|
||||
<text text-anchor="start" x="634.5" y="-446.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
|
||||
<text text-anchor="start" x="647.5" y="-446.3" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
|
||||
<text text-anchor="start" x="501.5" y="-428.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">registrar_id</text>
|
||||
<text text-anchor="start" x="634.5" y="-427.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
|
||||
<text text-anchor="start" x="647.5" y="-427.3" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
|
||||
<text text-anchor="start" x="501.5" y="-408.3" font-family="Helvetica,sans-Serif" font-size="14.00">login_email_address</text>
|
||||
<text text-anchor="start" x="634.5" y="-408.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
|
||||
<text text-anchor="start" x="647.5" y="-408.3" font-family="Helvetica,sans-Serif" font-size="14.00">text</text>
|
||||
<polygon fill="none" stroke="#888888" points="498.5,-401.5 498.5,-479.5 720.5,-479.5 720.5,-401.5 498.5,-401.5" />
|
||||
<polygon fill="#e9c2f2" stroke="transparent" points="499.5,-460.5 499.5,-479.5 645.5,-479.5 645.5,-460.5 499.5,-460.5" />
|
||||
<text text-anchor="start" x="501.5" y="-467.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."RegistrarPoc"</text>
|
||||
<polygon fill="#e9c2f2" stroke="transparent" points="645.5,-460.5 645.5,-479.5 719.5,-479.5 719.5,-460.5 645.5,-460.5" />
|
||||
<text text-anchor="start" x="680.5" y="-466.3" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
|
||||
<text text-anchor="start" x="501.5" y="-448.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">email_address</text>
|
||||
<text text-anchor="start" x="619.5" y="-447.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
|
||||
<text text-anchor="start" x="647.5" y="-447.3" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
|
||||
<text text-anchor="start" x="501.5" y="-429.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">registrar_id</text>
|
||||
<text text-anchor="start" x="619.5" y="-428.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
|
||||
<text text-anchor="start" x="647.5" y="-428.3" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
|
||||
<polygon fill="none" stroke="#888888" points="498.5,-422 498.5,-481 720.5,-481 720.5,-422 498.5,-422" />
|
||||
</g> <!-- registrarpoc_ab47054d->registrar_6e1503e3 -->
|
||||
<g id="edge76" class="edge">
|
||||
<title>
|
||||
registrarpoc_ab47054d:w->registrar_6e1503e3:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M480.42,-430.22C370.26,-426.89 305.01,-396.32 231,-484.5 196.2,-525.96 256.02,-1414.99 212.97,-1501.71" />
|
||||
<polygon fill="black" stroke="black" points="488.5,-430.35 498.43,-435 493.5,-430.42 498.5,-430.5 498.5,-430.5 498.5,-430.5 493.5,-430.42 498.57,-426 488.5,-430.35 488.5,-430.35" />
|
||||
<ellipse fill="none" stroke="black" cx="484.5" cy="-430.28" rx="4" ry="4" />
|
||||
<path fill="none" stroke="black" d="M480.44,-431.22C370.35,-427.81 305.12,-396.51 231,-484.5 196.13,-525.9 256.01,-1414.98 212.97,-1501.71" />
|
||||
<polygon fill="black" stroke="black" points="488.5,-431.34 498.43,-436 493.5,-431.42 498.5,-431.5 498.5,-431.5 498.5,-431.5 493.5,-431.42 498.57,-427 488.5,-431.34 488.5,-431.34" />
|
||||
<ellipse fill="none" stroke="black" cx="484.5" cy="-431.28" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="209.6,-1511.53 202.88,-1504.13 204.36,-1502.78 211.08,-1510.18 209.6,-1511.53" />
|
||||
<polyline fill="none" stroke="black" points="205.5,-1508.5 209.2,-1505.14 " />
|
||||
<polygon fill="black" stroke="black" points="213.3,-1508.16 206.58,-1500.76 208.06,-1499.42 214.78,-1506.82 213.3,-1508.16" />
|
||||
@@ -2208,27 +2205,27 @@ td.section {
|
||||
<title>
|
||||
registrarupdatehistory_8a38bed4:w->registrar_6e1503e3:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M1075.03,-316.53C1068.62,-325.21 1066.22,-338.59 1052,-344.5 928.1,-395.95 582.09,-356.67 449,-373.5 350.85,-385.91 294.38,-342.53 231,-418.5 194.01,-462.83 259.39,-1412.86 213.16,-1501.83" />
|
||||
<polygon fill="black" stroke="black" points="1082.51,-312.88 1093.47,-312.55 1087.01,-310.69 1091.5,-308.5 1091.5,-308.5 1091.5,-308.5 1087.01,-310.69 1089.53,-304.45 1082.51,-312.88 1082.51,-312.88" />
|
||||
<ellipse fill="none" stroke="black" cx="1078.92" cy="-314.63" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="209.54,-1511.61 202.97,-1504.07 204.48,-1502.76 211.05,-1510.3 209.54,-1511.61" />
|
||||
<polyline fill="none" stroke="black" points="205.5,-1508.5 209.27,-1505.22 " />
|
||||
<polygon fill="black" stroke="black" points="213.31,-1508.33 206.74,-1500.79 208.25,-1499.48 214.82,-1507.02 213.31,-1508.33" />
|
||||
<polyline fill="none" stroke="black" points="209.27,-1505.22 213.04,-1501.93 " />
|
||||
<text text-anchor="start" x="508.5" y="-377.3" font-family="Helvetica,sans-Serif" font-size="14.00">fkregistrarupdatehistoryregistrarid</text>
|
||||
<path fill="none" stroke="black" d="M1075.29,-316.72C1068.17,-327.97 1069.11,-347.77 1052,-356.5 932.41,-417.51 582.71,-381.43 449,-393.5 351.82,-402.27 296.63,-347.3 231,-419.5 192.2,-462.18 259.17,-1412.8 213.14,-1501.83" />
|
||||
<polygon fill="black" stroke="black" points="1082.58,-313.02 1093.54,-312.51 1087.04,-310.76 1091.5,-308.5 1091.5,-308.5 1091.5,-308.5 1087.04,-310.76 1089.46,-304.49 1082.58,-313.02 1082.58,-313.02" />
|
||||
<ellipse fill="none" stroke="black" cx="1079.01" cy="-314.83" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="209.54,-1511.61 202.96,-1504.08 204.47,-1502.76 211.05,-1510.29 209.54,-1511.61" />
|
||||
<polyline fill="none" stroke="black" points="205.5,-1508.5 209.27,-1505.21 " />
|
||||
<polygon fill="black" stroke="black" points="213.31,-1508.32 206.73,-1500.79 208.24,-1499.47 214.81,-1507 213.31,-1508.32" />
|
||||
<polyline fill="none" stroke="black" points="209.27,-1505.21 213.03,-1501.92 " />
|
||||
<text text-anchor="start" x="508.5" y="-397.3" font-family="Helvetica,sans-Serif" font-size="14.00">fkregistrarupdatehistoryregistrarid</text>
|
||||
</g> <!-- registrarupdatehistory_8a38bed4->user_f2216f01 -->
|
||||
<g id="edge87" class="edge">
|
||||
<title>
|
||||
registrarupdatehistory_8a38bed4:w->user_f2216f01:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M1073.16,-288.05C1007.37,-280.62 817.84,-246.96 788,-241.5 752.99,-235.09 742.65,-225.52 711.79,-223.78" />
|
||||
<polygon fill="black" stroke="black" points="1081.53,-288.71 1091.15,-293.99 1086.52,-289.11 1091.5,-289.5 1091.5,-289.5 1091.5,-289.5 1086.52,-289.11 1091.85,-285.01 1081.53,-288.71 1081.53,-288.71" />
|
||||
<ellipse fill="none" stroke="black" cx="1077.54" cy="-288.4" rx="4" ry="4" />
|
||||
<path fill="none" stroke="black" d="M1073.33,-289.35C951.73,-287.35 916.17,-264.96 788,-241.5 752.99,-235.09 742.65,-225.52 711.79,-223.78" />
|
||||
<polygon fill="black" stroke="black" points="1081.5,-289.42 1091.46,-294 1086.5,-289.46 1091.5,-289.5 1091.5,-289.5 1091.5,-289.5 1086.5,-289.46 1091.54,-285 1081.5,-289.42 1081.5,-289.42" />
|
||||
<ellipse fill="none" stroke="black" cx="1077.5" cy="-289.39" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="702.37,-228.53 702.63,-218.53 704.63,-218.58 704.36,-228.58 702.37,-228.53" />
|
||||
<polyline fill="none" stroke="black" points="701.5,-223.5 706.5,-223.63 " />
|
||||
<polygon fill="black" stroke="black" points="707.36,-228.66 707.63,-218.66 709.63,-218.72 709.36,-228.71 707.36,-228.66" />
|
||||
<polyline fill="none" stroke="black" points="706.5,-223.63 711.5,-223.77 " />
|
||||
<text text-anchor="start" x="829.5" y="-289.3" font-family="Helvetica,sans-Serif" font-size="14.00">fksr7w342s7x5s5jvdti2axqeq8</text>
|
||||
<text text-anchor="start" x="829.5" y="-293.3" font-family="Helvetica,sans-Serif" font-size="14.00">fksr7w342s7x5s5jvdti2axqeq8</text>
|
||||
</g> <!-- registrarpocupdatehistory_31e5d9aa -->
|
||||
<g id="node37" class="node">
|
||||
<title>
|
||||
@@ -2269,27 +2266,27 @@ td.section {
|
||||
<title>
|
||||
registrarpocupdatehistory_31e5d9aa:w->registrarpoc_ab47054d:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M1060.25,-412.4C945.91,-411.1 909.85,-398.18 788,-413.5 761.02,-416.89 753.22,-427.45 730.72,-429.96" />
|
||||
<path fill="none" stroke="black" d="M1060.25,-412.39C945.9,-411.02 909.74,-397.33 788,-413.5 760.95,-417.09 753.29,-428.27 730.75,-430.93" />
|
||||
<polygon fill="black" stroke="black" points="1068.5,-412.44 1078.47,-417 1073.5,-412.47 1078.5,-412.5 1078.5,-412.5 1078.5,-412.5 1073.5,-412.47 1078.53,-408 1068.5,-412.44 1068.5,-412.44" />
|
||||
<ellipse fill="none" stroke="black" cx="1064.5" cy="-412.42" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="721.76,-435.44 721.24,-425.45 723.23,-425.35 723.76,-435.34 721.76,-435.44" />
|
||||
<polyline fill="none" stroke="black" points="720.5,-430.5 725.49,-430.24 " />
|
||||
<polygon fill="black" stroke="black" points="726.75,-435.18 726.23,-425.19 728.23,-425.09 728.75,-435.07 726.75,-435.18" />
|
||||
<polyline fill="none" stroke="black" points="725.49,-430.24 730.49,-429.97 " />
|
||||
<polygon fill="black" stroke="black" points="721.78,-436.44 721.22,-426.45 723.22,-426.34 723.77,-436.33 721.78,-436.44" />
|
||||
<polyline fill="none" stroke="black" points="720.5,-431.5 725.49,-431.22 " />
|
||||
<polygon fill="black" stroke="black" points="726.77,-436.16 726.21,-426.17 728.21,-426.06 728.77,-436.05 726.77,-436.16" />
|
||||
<polyline fill="none" stroke="black" points="725.49,-431.22 730.48,-430.94 " />
|
||||
<text text-anchor="start" x="798" y="-417.3" font-family="Helvetica,sans-Serif" font-size="14.00">fkregistrarpocupdatehistoryemailaddress</text>
|
||||
</g> <!-- registrarpocupdatehistory_31e5d9aa->user_f2216f01 -->
|
||||
<g id="edge86" class="edge">
|
||||
<title>
|
||||
registrarpocupdatehistory_31e5d9aa:w->user_f2216f01:e
|
||||
</title>
|
||||
<path fill="none" stroke="black" d="M1060.51,-389.56C998,-372.91 800.77,-308.81 788,-301.5 746.24,-277.58 752.11,-230.72 711.54,-224.25" />
|
||||
<polygon fill="black" stroke="black" points="1068.73,-391.36 1077.54,-397.9 1073.62,-392.43 1078.5,-393.5 1078.5,-393.5 1078.5,-393.5 1073.62,-392.43 1079.46,-389.1 1068.73,-391.36 1068.73,-391.36" />
|
||||
<ellipse fill="none" stroke="black" cx="1064.82" cy="-390.51" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="702.13,-228.56 702.87,-218.59 704.86,-218.74 704.12,-228.71 702.13,-228.56" />
|
||||
<polyline fill="none" stroke="black" points="701.5,-223.5 706.49,-223.87 " />
|
||||
<polygon fill="black" stroke="black" points="707.11,-228.93 707.85,-218.96 709.85,-219.11 709.11,-229.08 707.11,-228.93" />
|
||||
<polyline fill="none" stroke="black" points="706.49,-223.87 711.47,-224.24 " />
|
||||
<text text-anchor="start" x="835.5" y="-390.3" font-family="Helvetica,sans-Serif" font-size="14.00">fkftpbwctxtkc1i0njc0tdcaa2g</text>
|
||||
<path fill="none" stroke="black" d="M1060.63,-389.15C998.08,-372.3 794.23,-312.16 788,-308.5 744.69,-283.09 753.78,-231.25 711.64,-224.28" />
|
||||
<polygon fill="black" stroke="black" points="1068.78,-391.13 1077.43,-397.87 1073.64,-392.32 1078.5,-393.5 1078.5,-393.5 1078.5,-393.5 1073.64,-392.32 1079.57,-389.13 1068.78,-391.13 1068.78,-391.13" />
|
||||
<ellipse fill="none" stroke="black" cx="1064.9" cy="-390.19" rx="4" ry="4" />
|
||||
<polygon fill="black" stroke="black" points="702.11,-228.56 702.88,-218.59 704.88,-218.75 704.11,-228.72 702.11,-228.56" />
|
||||
<polyline fill="none" stroke="black" points="701.5,-223.5 706.49,-223.88 " />
|
||||
<polygon fill="black" stroke="black" points="707.1,-228.95 707.87,-218.98 709.86,-219.13 709.09,-229.1 707.1,-228.95" />
|
||||
<polyline fill="none" stroke="black" points="706.49,-223.88 711.47,-224.27 " />
|
||||
<text text-anchor="start" x="835.5" y="-391.3" font-family="Helvetica,sans-Serif" font-size="14.00">fkftpbwctxtkc1i0njc0tdcaa2g</text>
|
||||
</g> <!-- registrylock_ac88663e -->
|
||||
<g id="node38" class="node">
|
||||
<title>
|
||||
@@ -6145,11 +6142,6 @@ td.section {
|
||||
<td class="minwidth"><b><i>registrar_id</i></b></td>
|
||||
<td class="minwidth">text not null</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spacer"></td>
|
||||
<td class="minwidth">login_email_address</td>
|
||||
<td class="minwidth">text</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3"></td>
|
||||
</tr>
|
||||
|
||||
@@ -173,3 +173,6 @@ V172__allocation_token_renewal_price.sql
|
||||
V173__create_feature_flag_table.sql
|
||||
V174__user_pkey.sql
|
||||
V175__user_update_history_id.sql
|
||||
V176__drop_login_email_address_column_from_registrar_poc.sql
|
||||
V177__drop_user_id.sql
|
||||
V178__drop_user_id_history.sql
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
-- Copyright 2024 The Nomulus Authors. All Rights Reserved.
|
||||
--
|
||||
-- Licensed under the Apache License, Version 2.0 (the "License");
|
||||
-- you may not use this file except in compliance with the License.
|
||||
-- You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing, software
|
||||
-- distributed under the License is distributed on an "AS IS" BASIS,
|
||||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
-- See the License for the specific language governing permissions and
|
||||
-- limitations under the License.
|
||||
|
||||
alter table "RegistrarPoc" drop column login_email_address;
|
||||
@@ -0,0 +1,15 @@
|
||||
-- Copyright 2024 The Nomulus Authors. All Rights Reserved.
|
||||
--
|
||||
-- Licensed under the Apache License, Version 2.0 (the "License");
|
||||
-- you may not use this file except in compliance with the License.
|
||||
-- You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing, software
|
||||
-- distributed under the License is distributed on an "AS IS" BASIS,
|
||||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
-- See the License for the specific language governing permissions and
|
||||
-- limitations under the License.
|
||||
|
||||
ALTER TABLE "User" DROP COLUMN id;
|
||||
@@ -0,0 +1,15 @@
|
||||
-- Copyright 2024 The Nomulus Authors. All Rights Reserved.
|
||||
--
|
||||
-- Licensed under the Apache License, Version 2.0 (the "License");
|
||||
-- you may not use this file except in compliance with the License.
|
||||
-- You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing, software
|
||||
-- distributed under the License is distributed on an "AS IS" BASIS,
|
||||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
-- See the License for the specific language governing permissions and
|
||||
-- limitations under the License.
|
||||
|
||||
ALTER TABLE "UserUpdateHistory" DROP COLUMN user_id;
|
||||
@@ -893,7 +893,6 @@
|
||||
global_role text not null,
|
||||
is_admin boolean not null,
|
||||
registrar_roles hstore,
|
||||
id int8,
|
||||
primary key (email_address)
|
||||
);
|
||||
|
||||
@@ -905,7 +904,6 @@
|
||||
history_type text not null,
|
||||
history_url text not null,
|
||||
email_address text not null,
|
||||
user_id int8 not null,
|
||||
registry_lock_email_address text,
|
||||
registry_lock_password_hash text,
|
||||
registry_lock_password_salt text,
|
||||
|
||||