From d33571dde31420023331cd8d88de5a4b9a25ea78 Mon Sep 17 00:00:00 2001 From: gbrodman Date: Mon, 29 Jul 2024 18:27:06 -0400 Subject: [PATCH] Change pkey of User to emailAddress (#2505) Originally, we though that User entities were going to have mutable email addresses, and thus would require a non-changing primary key. This proved to not be the case. It'll simplify the User loading/saving code if we just do everything by email address. Obviously this doesn't change much functionality, but it prepares us for removing the id field down the line once the changes propagate. --- .../google/registry/model/console/User.java | 34 +- .../registry/model/console/UserBase.java | 7 +- .../registry/model/console/UserDao.java | 20 +- .../model/console/UserUpdateHistory.java | 5 + .../registry/model/console/UserDaoTest.java | 11 +- .../registry/tools/GetUserCommandTest.java | 9 +- .../sql/er_diagram/brief_er_diagram.html | 1569 ++++++++--------- .../sql/er_diagram/full_er_diagram.html | 38 +- db/src/main/resources/sql/flyway.txt | 1 + .../resources/sql/flyway/V174__user_pkey.sql | 18 + .../sql/schema/db-schema.sql.generated | 20 +- .../resources/sql/schema/nomulus.golden.sql | 11 +- 12 files changed, 869 insertions(+), 874 deletions(-) create mode 100644 db/src/main/resources/sql/flyway/V174__user_pkey.sql diff --git a/core/src/main/java/google/registry/model/console/User.java b/core/src/main/java/google/registry/model/console/User.java index 7d2eead60..989f31578 100644 --- a/core/src/main/java/google/registry/model/console/User.java +++ b/core/src/main/java/google/registry/model/console/User.java @@ -14,9 +14,11 @@ package google.registry.model.console; +import static google.registry.persistence.transaction.TransactionManagerFactory.tm; 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.ImmutableMultimap; import com.google.common.flogger.FluentLogger; import google.registry.batch.CloudTasksUtils; @@ -27,25 +29,25 @@ import google.registry.tools.server.UpdateUserGroupAction; import google.registry.tools.server.UpdateUserGroupAction.Mode; import google.registry.util.RegistryEnvironment; import java.util.Optional; +import java.util.concurrent.atomic.AtomicLong; import javax.persistence.Access; import javax.persistence.AccessType; import javax.persistence.Embeddable; import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; import javax.persistence.Id; -import javax.persistence.Index; import javax.persistence.Table; /** A console user, either a registry employee or a registrar partner. */ @Embeddable @Entity -@Table(indexes = {@Index(columnList = "emailAddress", name = "user_email_address_idx")}) +@Table 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. * @@ -114,13 +116,18 @@ public class User extends UserBase { } @Override - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) @Access(AccessType.PROPERTY) public Long getId() { return super.getId(); } + @Id + @Override + @Access(AccessType.PROPERTY) + public String getEmailAddress() { + return super.getEmailAddress(); + } + @Override public Builder asBuilder() { return new Builder(clone(this)); @@ -139,5 +146,20 @@ 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(); + } } } diff --git a/core/src/main/java/google/registry/model/console/UserBase.java b/core/src/main/java/google/registry/model/console/UserBase.java index 9c2890bfb..1631e9da1 100644 --- a/core/src/main/java/google/registry/model/console/UserBase.java +++ b/core/src/main/java/google/registry/model/console/UserBase.java @@ -53,8 +53,7 @@ public class UserBase extends UpdateAutoTimestampEntity implements Buildable { @Transient private Long id; /** Email address of the user in question. */ - @Column(nullable = false) - String emailAddress; + @Transient String emailAddress; /** Optional external email address to use for registry lock confirmation emails. */ @Column String registryLockEmailAddress; @@ -90,6 +89,10 @@ public class UserBase extends UpdateAutoTimestampEntity implements Buildable { this.id = id; } + void setEmailAddress(String emailAddress) { + this.emailAddress = emailAddress; + } + public String getEmailAddress() { return emailAddress; } diff --git a/core/src/main/java/google/registry/model/console/UserDao.java b/core/src/main/java/google/registry/model/console/UserDao.java index c54044e2d..2694f424e 100644 --- a/core/src/main/java/google/registry/model/console/UserDao.java +++ b/core/src/main/java/google/registry/model/console/UserDao.java @@ -14,7 +14,6 @@ package google.registry.model.console; -import static com.google.common.base.Preconditions.checkArgument; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import java.util.Optional; @@ -32,23 +31,8 @@ public class UserDao { .findFirst()); } - /** Saves the given user, checking that no existing user already exists with this email. */ + /** Saves the given user, updating it if it already exists. */ public static void saveUser(User user) { - tm().transact( - () -> { - // Check for an existing user (the unique constraint protects us, but this gives a - // nicer exception) - Optional maybeSavedUser = loadUser(user.getEmailAddress()); - if (maybeSavedUser.isPresent()) { - User savedUser = maybeSavedUser.get(); - checkArgument( - savedUser.getId().equals(user.getId()), - String.format( - "Attempted save of User with email address %s and ID %s, user with that" - + " email already exists with ID %s", - user.getEmailAddress(), user.getId(), savedUser.getId())); - } - tm().put(user); - }); + tm().transact(() -> tm().put(user)); } } diff --git a/core/src/main/java/google/registry/model/console/UserUpdateHistory.java b/core/src/main/java/google/registry/model/console/UserUpdateHistory.java index cbf41083b..510f17ea3 100644 --- a/core/src/main/java/google/registry/model/console/UserUpdateHistory.java +++ b/core/src/main/java/google/registry/model/console/UserUpdateHistory.java @@ -42,6 +42,9 @@ public class UserUpdateHistory extends ConsoleUpdateHistory { @Column(nullable = false, name = "userId") Long id; + @Column(nullable = false, name = "emailAddress") + String emailAddress; + public UserBase getUser() { return user; } @@ -49,6 +52,7 @@ public class UserUpdateHistory extends ConsoleUpdateHistory { @PostLoad void postLoad() { user.setId(id); + user.setEmailAddress(emailAddress); } /** Creates a {@link VKey} instance for this entity. */ @@ -80,6 +84,7 @@ public class UserUpdateHistory extends ConsoleUpdateHistory { public Builder setUser(User user) { getInstance().user = user; getInstance().id = user.getId(); + getInstance().emailAddress = user.getEmailAddress(); return this; } } diff --git a/core/src/test/java/google/registry/model/console/UserDaoTest.java b/core/src/test/java/google/registry/model/console/UserDaoTest.java index f7bea44ba..4c48b8487 100644 --- a/core/src/test/java/google/registry/model/console/UserDaoTest.java +++ b/core/src/test/java/google/registry/model/console/UserDaoTest.java @@ -17,7 +17,6 @@ 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 static org.junit.jupiter.api.Assertions.assertThrows; import google.registry.model.EntityTestCase; import org.junit.jupiter.api.Test; @@ -64,7 +63,7 @@ public class UserDaoTest extends EntityTestCase { } @Test - void testFailure_sameEmail() { + void testSuccess_updateUser_sameEmail() { User user1 = new User.Builder() .setEmailAddress("email@email.com") @@ -73,12 +72,12 @@ public class UserDaoTest extends EntityTestCase { User user2 = new User.Builder() .setEmailAddress("email@email.com") - .setUserRoles(new UserRoles.Builder().setGlobalRole(GlobalRole.SUPPORT_AGENT).build()) + .setUserRoles(new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).build()) .build(); UserDao.saveUser(user1); - assertThrows(IllegalArgumentException.class, () -> UserDao.saveUser(user2)); + UserDao.saveUser(user2); assertAboutImmutableObjects() - .that(user1) - .isEqualExceptFields(UserDao.loadUser("email@email.com").get(), "id", "updateTimestamp"); + .that(user2) + .isEqualExceptFields(UserDao.loadUser("email@email.com").get(), "updateTimestamp"); } } diff --git a/core/src/test/java/google/registry/tools/GetUserCommandTest.java b/core/src/test/java/google/registry/tools/GetUserCommandTest.java index 910bca40a..3f8465ba3 100644 --- a/core/src/test/java/google/registry/tools/GetUserCommandTest.java +++ b/core/src/test/java/google/registry/tools/GetUserCommandTest.java @@ -28,6 +28,7 @@ public class GetUserCommandTest extends CommandTestCase { @BeforeEach void beforeEach() { + User.ID_GENERATOR_FOR_TESTING.set(0L); UserDao.saveUser( new User.Builder() .setEmailAddress("johndoe@theregistrar.com") @@ -52,7 +53,7 @@ public class GetUserCommandTest extends CommandTestCase { """ User: { emailAddress=fte@google.com - id=2 + id=1 registryLockEmailAddress=null registryLockPasswordHash=null registryLockPasswordSalt=null @@ -75,7 +76,7 @@ public class GetUserCommandTest extends CommandTestCase { """ User: { emailAddress=johndoe@theregistrar.com - id=1 + id=0 registryLockEmailAddress=null registryLockPasswordHash=null registryLockPasswordSalt=null @@ -90,7 +91,7 @@ public class GetUserCommandTest extends CommandTestCase { } User: { emailAddress=fte@google.com - id=2 + id=1 registryLockEmailAddress=null registryLockPasswordHash=null registryLockPasswordSalt=null @@ -113,7 +114,7 @@ public class GetUserCommandTest extends CommandTestCase { """ User: { emailAddress=johndoe@theregistrar.com - id=1 + id=0 registryLockEmailAddress=null registryLockPasswordHash=null registryLockPasswordSalt=null diff --git a/db/src/main/resources/sql/er_diagram/brief_er_diagram.html b/db/src/main/resources/sql/er_diagram/brief_er_diagram.html index 732cd8cfe..8756cbde4 100644 --- a/db/src/main/resources/sql/er_diagram/brief_er_diagram.html +++ b/db/src/main/resources/sql/er_diagram/brief_er_diagram.html @@ -257,30 +257,30 @@ td.section { generated by - SchemaCrawler 16.21.2 + SchemaCrawler 16.21.4 generated on - 2024-06-20 20:07:02 + 2024-07-25 18:42:06 last flyway file - V173__create_feature_flag_table.sql + V174__user_pkey.sql

 

 

- - + + SchemaCrawler_Diagram - + generated by - SchemaCrawler 16.21.2 + SchemaCrawler 16.21.4 generated on - 2024-06-20 20:07:02 + 2024-07-25 18:42:06 @@ -348,144 +348,144 @@ td.section { billingevent_a57d1815:w->allocationtoken_a08ccbef:e - + - - - - - fk_billing_event_allocation_token + + + + + fk_billing_event_allocation_token domainhistory_a54cc226 - - public."DomainHistory" - - [table] - history_revision_id - - int8 not null - history_registrar_id - - text - history_modification_time - - timestamptz not null - history_type - - text not null - creation_time - - timestamptz - domain_repo_id - - text not null - current_package_token - - text - + + public."DomainHistory" + + [table] + history_revision_id + + int8 not null + history_registrar_id + + text + history_modification_time + + timestamptz not null + history_type + + text not null + creation_time + + timestamptz + domain_repo_id + + text not null + current_package_token + + text + billingevent_a57d1815:w->domainhistory_a54cc226:e - + - - - - + + + + fk_billing_event_domain_history billingevent_a57d1815:w->domainhistory_a54cc226:e - + - - - - + + + + fk_billing_event_domain_history billingevent_a57d1815:w->domainhistory_a54cc226:e - + - - - - + + + + fk_billing_event_recurrence_history billingevent_a57d1815:w->domainhistory_a54cc226:e - + - - - - + + + + fk_billing_event_recurrence_history billingrecurrence_5fa2cb01 - - public."BillingRecurrence" - - [table] - billing_recurrence_id - - int8 not null - registrar_id - - text not null - domain_history_revision_id - - int8 not null - domain_repo_id - - text not null - event_time - - timestamptz not null - recurrence_end_time - - timestamptz - recurrence_time_of_year - - text - recurrence_last_expansion - - timestamptz not null - + + public."BillingRecurrence" + + [table] + billing_recurrence_id + + int8 not null + registrar_id + + text not null + domain_history_revision_id + + int8 not null + domain_repo_id + + text not null + event_time + + timestamptz not null + recurrence_end_time + + timestamptz + recurrence_time_of_year + + text + recurrence_last_expansion + + timestamptz not null + billingevent_a57d1815:w->billingrecurrence_5fa2cb01:e - + - - - - - fk_billing_event_cancellation_matching_billing_recurrence_id + + + + + fk_billing_event_cancellation_matching_billing_recurrence_id @@ -669,26 +669,26 @@ td.section { <title> domain_6c51cffa:w->billingrecurrence_5fa2cb01:e - + - - - - + + + + fk_domain_billing_recurrence_id domain_6c51cffa:w->billingrecurrence_5fa2cb01:e - + - - - - + + + + fk_domain_transfer_billing_recurrence_id @@ -878,22 +878,22 @@ td.section { domainhistory_a54cc226:w->allocationtoken_a08ccbef:e - - - - + + + + - fk_domain_history_current_package_token + fk_domain_history_current_package_token domainhistory_a54cc226:w->domain_6c51cffa:e - - - + + + @@ -904,14 +904,14 @@ td.section { domainhistory_a54cc226:w->registrar_6e1503e3:e - - - - - - - - fk_domain_history_registrar_id + + + + + + + + fk_domain_history_registrar_id @@ -930,40 +930,40 @@ td.section { <title> billingcancellation_6eedf614:w->domainhistory_a54cc226:e - + - - - - - fk_billing_cancellation_domain_history + + + + + fk_billing_cancellation_domain_history billingcancellation_6eedf614:w->domainhistory_a54cc226:e - + - - - - - fk_billing_cancellation_domain_history + + + + + fk_billing_cancellation_domain_history billingcancellation_6eedf614:w->billingrecurrence_5fa2cb01:e - - - - - - - - fk_billing_cancellation_billing_recurrence_id + + + + + + + + fk_billing_cancellation_billing_recurrence_id @@ -1033,185 +1033,185 @@ td.section { <title> graceperiod_cd3b2e8f:w->billingrecurrence_5fa2cb01:e - + - - - - - fk_grace_period_billing_recurrence_id + + + + + fk_grace_period_billing_recurrence_id graceperiod_cd3b2e8f:w->registrar_6e1503e3:e - + - - - - + + + + fk_grace_period_registrar_id billingrecurrence_5fa2cb01:w->domainhistory_a54cc226:e - - - - - - - + + + + + + + fk_billing_recurrence_domain_history billingrecurrence_5fa2cb01:w->domainhistory_a54cc226:e - - - - - - - - fk_billing_recurrence_domain_history + + + + + + + + fk_billing_recurrence_domain_history billingrecurrence_5fa2cb01:w->registrar_6e1503e3:e - - - - - - - + + + + + + + fk_billing_recurrence_registrar_id bsadomainrefresh_c8f4c45d - - public."BsaDomainRefresh" - - [table] - job_id - - bigserial not null - - auto-incremented - + + public."BsaDomainRefresh" + + [table] + job_id + + bigserial not null + + auto-incremented + bsadownload_98d031ce - - public."BsaDownload" - - [table] - job_id - - bigserial not null - - auto-incremented - creation_time - - timestamptz not null - + + public."BsaDownload" + + [table] + job_id + + bigserial not null + + auto-incremented + creation_time + + timestamptz not null + bsalabel_2755e1da - - public."BsaLabel" - - [table] - label - - text not null - + + public."BsaLabel" + + [table] + label + + text not null + bsaunblockabledomain_b739a38 - - public."BsaUnblockableDomain" - - [table] - label - - text not null - tld - - text not null - + + public."BsaUnblockableDomain" + + [table] + label + + text not null + tld + + text not null + bsaunblockabledomain_b739a38:w->bsalabel_2755e1da:e - - - - - - - - fkbsaunblockabledomainlabel + + + + + + + + fkbsaunblockabledomainlabel claimsentry_105da9f1 - - public."ClaimsEntry" - - [table] - revision_id - - int8 not null - domain_label - - text not null - + + public."ClaimsEntry" + + [table] + revision_id + + int8 not null + domain_label + + text not null + claimslist_3d49bc2b - - public."ClaimsList" - - [table] - revision_id - - bigserial not null - - auto-incremented - + + public."ClaimsList" + + [table] + revision_id + + bigserial not null + + auto-incremented + claimsentry_105da9f1:w->claimslist_3d49bc2b:e - - - - - - - - fk6sc6at5hedffc0nhdcab6ivuq + + + + + + + + fk6sc6at5hedffc0nhdcab6ivuq @@ -1239,32 +1239,27 @@ td.section { <title> user_f2216f01 - - public."User" - - [table] - id - - bigserial not null - - auto-incremented - email_address - - text not null - + + public."User" + + [table] + email_address + + text not null + consoleeppactionhistory_bcc2a2c6:w->user_f2216f01:e - - - - - - - - fkb686b9os2nsjpv930npa4r3b4 + + + + + + + + fkb686b9os2nsjpv930npa4r3b4 @@ -1335,37 +1330,37 @@ td.section { <title> contacthistory_d2964f8a - - public."ContactHistory" - - [table] - history_revision_id - - int8 not null - history_registrar_id - - text - history_modification_time - - timestamptz not null - history_type - - text not null - creation_time - - timestamptz - contact_repo_id - - text not null - + + public."ContactHistory" + + [table] + history_revision_id + + int8 not null + history_registrar_id + + text + history_modification_time + + timestamptz not null + history_type + + text not null + creation_time + + timestamptz + contact_repo_id + + text not null + contacthistory_d2964f8a:w->contact_8de8cb16:e - - - + + + @@ -1376,104 +1371,104 @@ td.section { contacthistory_d2964f8a:w->registrar_6e1503e3:e - - - - + + + + - + - fk_contact_history_registrar_id + fk_contact_history_registrar_id pollmessage_614a523e - - public."PollMessage" - - [table] - poll_message_id - - int8 not null - registrar_id - - text not null - contact_repo_id - - text - contact_history_revision_id - - int8 - domain_repo_id - - text - domain_history_revision_id - - int8 - event_time - - timestamptz not null - host_repo_id - - text - host_history_revision_id - - int8 - transfer_response_gaining_registrar_id - - text - transfer_response_losing_registrar_id - - text - + + public."PollMessage" + + [table] + poll_message_id + + int8 not null + registrar_id + + text not null + contact_repo_id + + text + contact_history_revision_id + + int8 + domain_repo_id + + text + domain_history_revision_id + + int8 + event_time + + timestamptz not null + host_repo_id + + text + host_history_revision_id + + int8 + transfer_response_gaining_registrar_id + + text + transfer_response_losing_registrar_id + + text + pollmessage_614a523e:w->domain_6c51cffa:e - - - - - - - + + + + + + + fk_poll_message_domain_repo_id pollmessage_614a523e:w->domainhistory_a54cc226:e - - - - - - - + + + + + + + fk_poll_message_domain_history pollmessage_614a523e:w->domainhistory_a54cc226:e - - - - - - - + + + + + + + fk_poll_message_domain_history pollmessage_614a523e:w->contact_8de8cb16:e - - - + + + @@ -1484,27 +1479,27 @@ td.section { pollmessage_614a523e:w->contacthistory_d2964f8a:e - - - - - - - - fk_poll_message_contact_history + + + + + + + + fk_poll_message_contact_history pollmessage_614a523e:w->contacthistory_d2964f8a:e - - - - - - - - fk_poll_message_contact_history + + + + + + + + fk_poll_message_contact_history @@ -1547,105 +1542,105 @@ td.section { <title> pollmessage_614a523e:w->host_f21b78de:e - - - + + + - fk_poll_message_host_repo_id + fk_poll_message_host_repo_id hosthistory_56210c2 - - public."HostHistory" - - [table] - history_revision_id - - int8 not null - history_registrar_id - - text not null - history_modification_time - - timestamptz not null - history_type - - text not null - host_name - - text - creation_time - - timestamptz - host_repo_id - - text not null - + + public."HostHistory" + + [table] + history_revision_id + + int8 not null + history_registrar_id + + text not null + history_modification_time + + timestamptz not null + history_type + + text not null + host_name + + text + creation_time + + timestamptz + host_repo_id + + text not null + pollmessage_614a523e:w->hosthistory_56210c2:e - - - - - - - - fk_poll_message_host_history + + + + + + + + fk_poll_message_host_history pollmessage_614a523e:w->hosthistory_56210c2:e - - - - - - - - fk_poll_message_host_history + + + + + + + + fk_poll_message_host_history pollmessage_614a523e:w->registrar_6e1503e3:e - - - + + + - + - fk_poll_message_registrar_id + fk_poll_message_registrar_id pollmessage_614a523e:w->registrar_6e1503e3:e - - - + + + - fk_poll_message_transfer_response_gaining_registrar_id + fk_poll_message_transfer_response_gaining_registrar_id pollmessage_614a523e:w->registrar_6e1503e3:e - - - + + + @@ -1656,17 +1651,17 @@ td.section { cursor_6af40e8c - - public."Cursor" - - [table] - "scope" - - text not null - type - - text not null - + + public."Cursor" + + [table] + "scope" + + text not null + type + + text not null + @@ -1710,46 +1705,46 @@ td.section { <title> dnsrefreshrequest_4e6affb3 - - public."DnsRefreshRequest" - - [table] - id - - bigserial not null - - auto-incremented - request_time - - timestamptz not null - last_process_time - - timestamptz not null - + + public."DnsRefreshRequest" + + [table] + id + + bigserial not null + + auto-incremented + request_time + + timestamptz not null + last_process_time + + timestamptz not null + domainhost_1ea127c2 - - public."DomainHost" - - [table] - domain_repo_id - - text not null - host_repo_id - - text - + + public."DomainHost" + + [table] + domain_repo_id + + text not null + host_repo_id + + text + domainhost_1ea127c2:w->domain_6c51cffa:e - - - + + + @@ -1760,27 +1755,27 @@ td.section { domainhost_1ea127c2:w->host_f21b78de:e - - - + + + - + - fk_domainhost_host_valid + fk_domainhost_host_valid host_f21b78de:w->domain_6c51cffa:e - - - + + + - fk_host_superordinate_domain + fk_host_superordinate_domain @@ -1844,26 +1839,26 @@ td.section { <title> domaindsdatahistory_995b060d:w->domainhistory_a54cc226:e - + - - - - + + + + fko4ilgyyfnvppbpuivus565i0j domaindsdatahistory_995b060d:w->domainhistory_a54cc226:e - - - - - - - + + + + + + + fko4ilgyyfnvppbpuivus565i0j @@ -1889,26 +1884,26 @@ td.section { domainhistoryhost_9f3f23ee:w->domainhistory_a54cc226:e - + - - - - + + + + fka9woh3hu8gx5x0vly6bai327n domainhistoryhost_9f3f23ee:w->domainhistory_a54cc226:e - + - - - - + + + + fka9woh3hu8gx5x0vly6bai327n @@ -1939,26 +1934,26 @@ td.section { domaintransactionrecord_6e77ff61:w->domainhistory_a54cc226:e - + - - - - + + + + fkcjqe54u72kha71vkibvxhjye7 domaintransactionrecord_6e77ff61:w->domainhistory_a54cc226:e - + - - - - + + + + fkcjqe54u72kha71vkibvxhjye7 @@ -1997,61 +1992,61 @@ td.section { graceperiodhistory_40ccc1f1:w->domainhistory_a54cc226:e - + - - - - + + + + fk7w3cx8d55q8bln80e716tr7b8 graceperiodhistory_40ccc1f1:w->domainhistory_a54cc226:e - - + + - - - - - fk7w3cx8d55q8bln80e716tr7b8 + + + + + fk7w3cx8d55q8bln80e716tr7b8 featureflag_3ee43a78 - - public."FeatureFlag" - - [table] - feature_name - - text not null - + + public."FeatureFlag" + + [table] + feature_name + + text not null + hosthistory_56210c2:w->host_f21b78de:e - - - + + + - - + + fk_hosthistory_host hosthistory_56210c2:w->registrar_6e1503e3:e - - - + + + @@ -2062,101 +2057,101 @@ td.section { lock_f21d4861 - - public."Lock" - - [table] - resource_name - - text not null - "scope" - - text not null - + + public."Lock" + + [table] + resource_name + + text not null + "scope" + + text not null + packagepromotion_56aa33 - - public."PackagePromotion" - - [table] - package_promotion_id - - bigserial not null - - auto-incremented - token - - text not null - + + public."PackagePromotion" + + [table] + package_promotion_id + + bigserial not null + + auto-incremented + token + + text not null + premiumentry_b0060b91 - - public."PremiumEntry" - - [table] - revision_id - - int8 not null - domain_label - - text not null - + + public."PremiumEntry" + + [table] + revision_id + + int8 not null + domain_label + + text not null + premiumlist_7c3ea68b - - public."PremiumList" - - [table] - revision_id - - bigserial not null - - auto-incremented - name - - text not null - + + public."PremiumList" + + [table] + revision_id + + bigserial not null + + auto-incremented + name + + text not null + premiumentry_b0060b91:w->premiumlist_7c3ea68b:e - - - - - - - - fko0gw90lpo1tuee56l0nb6y6g5 + + + + + + + + fko0gw90lpo1tuee56l0nb6y6g5 rderevision_83396864 - - public."RdeRevision" - - [table] - tld - - text not null - mode - - text not null - "date" - - date not null - + + public."RdeRevision" + + [table] + tld + + text not null + mode + + text not null + "date" + + date not null + @@ -2213,9 +2208,9 @@ td.section { <title> registrarupdatehistory_8a38bed4:w->registrar_6e1503e3:e - - - + + + @@ -2226,14 +2221,14 @@ td.section { registrarupdatehistory_8a38bed4:w->user_f2216f01:e - - - - - - - - fksr7w342s7x5s5jvdti2axqeq8 + + + + + + + + fksr7w342s7x5s5jvdti2axqeq8 @@ -2287,195 +2282,195 @@ td.section { <title> registrarpocupdatehistory_31e5d9aa:w->user_f2216f01:e - - - - - - - - fkftpbwctxtkc1i0njc0tdcaa2g + + + + + + + + fkftpbwctxtkc1i0njc0tdcaa2g registrylock_ac88663e - - public."RegistryLock" - - [table] - revision_id - - bigserial not null - - auto-incremented - registrar_id - - text not null - repo_id - - text not null - verification_code - - text not null - relock_revision_id - - int8 - + + public."RegistryLock" + + [table] + revision_id + + bigserial not null + + auto-incremented + registrar_id + + text not null + repo_id + + text not null + verification_code + + text not null + relock_revision_id + + int8 + registrylock_ac88663e:w->registrylock_ac88663e:e - - - - - - - - fk2lhcwpxlnqijr96irylrh1707 + + + + + + + + fk2lhcwpxlnqijr96irylrh1707 reservedentry_1a7b8520 - - public."ReservedEntry" - - [table] - revision_id - - int8 not null - domain_label - - text not null - + + public."ReservedEntry" + + [table] + revision_id + + int8 not null + domain_label + + text not null + reservedlist_b97c3f1c - - public."ReservedList" - - [table] - revision_id - - bigserial not null - - auto-incremented - name - - text not null - + + public."ReservedList" + + [table] + revision_id + + bigserial not null + + auto-incremented + name + + text not null + reservedentry_1a7b8520:w->reservedlist_b97c3f1c:e - - - - - - - - fkgq03rk0bt1hb915dnyvd3vnfc + + + + + + + + fkgq03rk0bt1hb915dnyvd3vnfc serversecret_6cc90f09 - - public."ServerSecret" - - [table] - id - - int8 not null - + + public."ServerSecret" + + [table] + id + + int8 not null + signedmarkrevocationentry_99c39721 - - public."SignedMarkRevocationEntry" - - [table] - revision_id - - int8 not null - smd_id - - text not null - + + public."SignedMarkRevocationEntry" + + [table] + revision_id + + int8 not null + smd_id + + text not null + signedmarkrevocationlist_c5d968fb - - public."SignedMarkRevocationList" - - [table] - revision_id - - bigserial not null - - auto-incremented - + + public."SignedMarkRevocationList" + + [table] + revision_id + + bigserial not null + + auto-incremented + signedmarkrevocationentry_99c39721:w->signedmarkrevocationlist_c5d968fb:e - - - - - - - - fk5ivlhvs3121yx2li5tqh54u4 + + + + + + + + fk5ivlhvs3121yx2li5tqh54u4 spec11threatmatch_a61228a6 - - public."Spec11ThreatMatch" - - [table] - id - - bigserial not null - - auto-incremented - check_date - - date not null - registrar_id - - text not null - tld - - text not null - + + public."Spec11ThreatMatch" + + [table] + id + + bigserial not null + + auto-incremented + check_date + + date not null + registrar_id + + text not null + tld + + text not null + tmchcrl_d282355 - - public."TmchCrl" - - [table] - id - - int8 not null - + + public."TmchCrl" + + [table] + id + + int8 not null + @@ -2500,26 +2495,26 @@ td.section { <title> userupdatehistory_24efd476:w->user_f2216f01:e - + - - - - - + + + + + fkuserupdatehistoryemailaddress userupdatehistory_24efd476:w->user_f2216f01:e - - - - - - - + + + + + + + fk1s7bopbl3pwrhv3jkkofnv3o0 @@ -6854,17 +6849,7 @@ td.section { - id - bigserial not null - - - - - auto-incremented - - - - email_address + email_address text not null @@ -6882,7 +6867,7 @@ td.section { - id + email_address diff --git a/db/src/main/resources/sql/er_diagram/full_er_diagram.html b/db/src/main/resources/sql/er_diagram/full_er_diagram.html index d857aba49..8744458f4 100644 --- a/db/src/main/resources/sql/er_diagram/full_er_diagram.html +++ b/db/src/main/resources/sql/er_diagram/full_er_diagram.html @@ -257,15 +257,15 @@ td.section { generated by - SchemaCrawler 16.21.2 + SchemaCrawler 16.21.4 generated on - 2024-06-20 20:07:00 + 2024-07-25 18:42:05 last flyway file - V173__create_feature_flag_table.sql + V174__user_pkey.sql @@ -278,9 +278,9 @@ td.section { generated by - SchemaCrawler 16.21.2 + SchemaCrawler 16.21.4 generated on - 2024-06-20 20:07:00 + 2024-07-25 18:42:05 @@ -2071,12 +2071,12 @@ td.section { <text text-anchor="start" x="713" y="-504.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."User"</text> <polygon fill="#e9c2f2" stroke="transparent" points="901,-497.5 901,-516.5 1011,-516.5 1011,-497.5 901,-497.5" /> <text text-anchor="start" x="972" y="-503.3" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text> - <text text-anchor="start" x="713" y="-485.3" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">id</text> + <text text-anchor="start" x="713" y="-484.3" font-family="Helvetica,sans-Serif" font-size="14.00">id</text> <text text-anchor="start" x="895" y="-484.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text> - <text text-anchor="start" x="903" y="-484.3" font-family="Helvetica,sans-Serif" font-size="14.00">bigserial not null</text> + <text text-anchor="start" x="903" y="-484.3" font-family="Helvetica,sans-Serif" font-size="14.00">bigserial</text> <text text-anchor="start" x="895" y="-465.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text> <text text-anchor="start" x="903" y="-465.3" font-family="Helvetica,sans-Serif" font-size="14.00">auto-incremented</text> - <text text-anchor="start" x="713" y="-446.3" font-family="Helvetica,sans-Serif" font-size="14.00">email_address</text> + <text text-anchor="start" x="713" 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="895" y="-446.3" font-family="Helvetica,sans-Serif" font-size="14.00"> </text> <text text-anchor="start" x="903" y="-446.3" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text> <text text-anchor="start" x="713" y="-427.3" font-family="Helvetica,sans-Serif" font-size="14.00">registry_lock_password_hash</text> @@ -13113,8 +13113,8 @@ td.section { <tbody> <tr> <td class="spacer"></td> - <td class="minwidth"><b><i>id</i></b></td> - <td class="minwidth">bigserial not null</td> + <td class="minwidth">id</td> + <td class="minwidth">bigserial</td> </tr> <tr> <td class="spacer"></td> @@ -13123,7 +13123,7 @@ td.section { </tr> <tr> <td class="spacer"></td> - <td class="minwidth">email_address</td> + <td class="minwidth"><b><i>email_address</i></b></td> <td class="minwidth">text not null</td> </tr> <tr> @@ -13176,7 +13176,7 @@ td.section { </tr> <tr> <td class="spacer"></td> - <td class="minwidth">id</td> + <td class="minwidth">email_address</td> <td class="minwidth"></td> </tr> <tr> @@ -13260,7 +13260,7 @@ td.section { </tr> <tr> <td class="spacer"></td> - <td class="minwidth">id</td> + <td class="minwidth">email_address</td> <td class="minwidth">ascending</td> </tr> <tr> @@ -13275,18 +13275,6 @@ td.section { <td class="minwidth">email_address</td> <td class="minwidth">ascending</td> </tr> - <tr> - <td colspan="3"></td> - </tr> - <tr> - <td colspan="2" class="name">user_email_address_idx</td> - <td class="description right">[non-unique index]</td> - </tr> - <tr> - <td class="spacer"></td> - <td class="minwidth">email_address</td> - <td class="minwidth">ascending</td> - </tr> </tbody> </table> <p> </p> diff --git a/db/src/main/resources/sql/flyway.txt b/db/src/main/resources/sql/flyway.txt index 09cd7798b..cc5511486 100644 --- a/db/src/main/resources/sql/flyway.txt +++ b/db/src/main/resources/sql/flyway.txt @@ -171,3 +171,4 @@ V170__user_update_registry_lock_email.sql V171__drop_create_billing_cost_columns_from_tld.sql V172__allocation_token_renewal_price.sql V173__create_feature_flag_table.sql +V174__user_pkey.sql diff --git a/db/src/main/resources/sql/flyway/V174__user_pkey.sql b/db/src/main/resources/sql/flyway/V174__user_pkey.sql new file mode 100644 index 000000000..c425998d6 --- /dev/null +++ b/db/src/main/resources/sql/flyway/V174__user_pkey.sql @@ -0,0 +1,18 @@ +-- 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 CONSTRAINT "User_pkey"; +ALTER TABLE "User" ADD CONSTRAINT "User_pkey" PRIMARY KEY (email_address); +ALTER TABLE "User" ALTER COLUMN id DROP NOT NULL; +DROP INDEX user_email_address_idx; diff --git a/db/src/main/resources/sql/schema/db-schema.sql.generated b/db/src/main/resources/sql/schema/db-schema.sql.generated index fc6ba6efd..544fb985a 100644 --- a/db/src/main/resources/sql/schema/db-schema.sql.generated +++ b/db/src/main/resources/sql/schema/db-schema.sql.generated @@ -885,16 +885,16 @@ ); create table "User" ( - id bigserial not null, + email_address text not null, update_timestamp timestamptz, - email_address text not null, registry_lock_email_address text, registry_lock_password_hash text, registry_lock_password_salt text, global_role text not null, is_admin boolean not null, registrar_roles hstore, - primary key (id) + id int8, + primary key (email_address) ); create table "UserUpdateHistory" ( @@ -904,8 +904,8 @@ history_request_body text, history_type text not null, history_url text not null, - user_id int8 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, @@ -1016,17 +1016,13 @@ create index reservedlist_name_idx on "ReservedList" (name); create index spec11threatmatch_registrar_id_idx on "Spec11ThreatMatch" (registrar_id); create index spec11threatmatch_tld_idx on "Spec11ThreatMatch" (tld); create index spec11threatmatch_check_date_idx on "Spec11ThreatMatch" (check_date); -create index user_email_address_idx on "User" (email_address); - - alter table if exists "User" - add constraint UK_seshmd8qn3lcffsjw5j8wnbnd unique (email_address); create index IDXbjacjlm8ianc4kxxvamnu94k5 on "UserUpdateHistory" (history_acting_user); create index IDX5yqacw829y5bm6f7eajsq1cts on "UserUpdateHistory" (email_address); alter table if exists "ConsoleEppActionHistory" add constraint FKb686b9os2nsjpv930npa4r3b4 foreign key (history_acting_user) - references "User" (email_address); + references "User"; alter table if exists "DelegationSignerData" add constraint FKtr24j9v14ph2mfuw2gsmt12kq @@ -1066,12 +1062,12 @@ create index IDX5yqacw829y5bm6f7eajsq1cts on "UserUpdateHistory" (email_address) alter table if exists "RegistrarPocUpdateHistory" add constraint FKftpbwctxtkc1i0njc0tdcaa2g foreign key (history_acting_user) - references "User" (email_address); + references "User"; alter table if exists "RegistrarUpdateHistory" add constraint FKsr7w342s7x5s5jvdti2axqeq8 foreign key (history_acting_user) - references "User" (email_address); + references "User"; alter table if exists "RegistryLock" add constraint FK2lhcwpxlnqijr96irylrh1707 @@ -1086,4 +1082,4 @@ create index IDX5yqacw829y5bm6f7eajsq1cts on "UserUpdateHistory" (email_address) alter table if exists "UserUpdateHistory" add constraint FK1s7bopbl3pwrhv3jkkofnv3o0 foreign key (history_acting_user) - references "User" (email_address); + references "User"; diff --git a/db/src/main/resources/sql/schema/nomulus.golden.sql b/db/src/main/resources/sql/schema/nomulus.golden.sql index 996a29e4d..48230f613 100644 --- a/db/src/main/resources/sql/schema/nomulus.golden.sql +++ b/db/src/main/resources/sql/schema/nomulus.golden.sql @@ -1317,7 +1317,7 @@ CREATE TABLE public."TmchCrl" ( -- CREATE TABLE public."User" ( - id bigint NOT NULL, + id bigint, email_address text NOT NULL, registry_lock_password_hash text, registry_lock_password_salt text, @@ -1833,7 +1833,7 @@ ALTER TABLE ONLY public."UserUpdateHistory" -- ALTER TABLE ONLY public."User" - ADD CONSTRAINT "User_pkey" PRIMARY KEY (id); + ADD CONSTRAINT "User_pkey" PRIMARY KEY (email_address); -- @@ -2547,13 +2547,6 @@ CREATE INDEX spec11threatmatch_registrar_id_idx ON public."Spec11ThreatMatch" US CREATE INDEX spec11threatmatch_tld_idx ON public."Spec11ThreatMatch" USING btree (tld); --- --- Name: user_email_address_idx; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX user_email_address_idx ON public."User" USING btree (email_address); - - -- -- Name: UserUpdateHistory fk1s7bopbl3pwrhv3jkkofnv3o0; Type: FK CONSTRAINT; Schema: public; Owner: - --