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: - --