mirror of
https://github.com/google/nomulus
synced 2026-07-11 10:32:21 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fd7820759d | |||
| 69359bb1e6 | |||
| 35b602a76e | |||
| 82002d1f75 | |||
| 2fd9b062df | |||
| ec3804e87e | |||
| d0d28cc7e6 | |||
| 2d1260c01b | |||
| 06da6a2cc6 | |||
| 858a22f82e | |||
| 3c126ddfd4 |
Generated
+3
-3
@@ -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
|
||||
|
||||
@@ -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;
|
||||
@@ -278,22 +275,14 @@ public final class OteAccountBuilder {
|
||||
/** 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) {
|
||||
|
||||
@@ -15,11 +15,9 @@
|
||||
package google.registry.model.console;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
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.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
@@ -34,7 +32,6 @@ 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;
|
||||
@@ -52,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.
|
||||
*
|
||||
@@ -163,12 +158,6 @@ public class User extends UserBase {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Access(AccessType.PROPERTY)
|
||||
public Long getId() {
|
||||
return super.getId();
|
||||
}
|
||||
|
||||
@Id
|
||||
@Override
|
||||
@Access(AccessType.PROPERTY)
|
||||
@@ -183,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. */
|
||||
@@ -194,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);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-2
@@ -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,11 +16,12 @@ 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.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;
|
||||
@@ -40,7 +41,8 @@ public class CreateUserCommand extends CreateOrUpdateUserCommand implements Comm
|
||||
@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;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,15 +14,15 @@
|
||||
|
||||
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.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;
|
||||
@@ -46,7 +46,9 @@ public class DeleteUserCommand extends ConfirmingCommand implements CommandWithC
|
||||
@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);
|
||||
}
|
||||
|
||||
@@ -54,9 +56,9 @@ public class DeleteUserCommand extends ConfirmingCommand implements CommandWithC
|
||||
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, null, connection, iamClient);
|
||||
return String.format("Deleted user with email %s", email);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+15
-2
@@ -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(
|
||||
|
||||
+1
-2
@@ -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,8 +259,8 @@ 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, null, iamClient);
|
||||
data.put("password", password);
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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,6 +16,7 @@ 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;
|
||||
@@ -28,7 +29,6 @@ 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.DatabaseHelper;
|
||||
import google.registry.tools.server.UpdateUserGroupAction;
|
||||
import java.util.Optional;
|
||||
@@ -93,14 +93,14 @@ 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);
|
||||
verifyNoInteractions(connection);
|
||||
@@ -109,7 +109,7 @@ public class CreateUserCommandTest extends CommandTestCase<CreateUserCommand> {
|
||||
@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);
|
||||
@@ -123,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",
|
||||
|
||||
@@ -24,7 +24,8 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.net.MediaType;
|
||||
import google.registry.model.console.UserDao;
|
||||
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;
|
||||
@@ -47,9 +48,10 @@ public class DeleteUserCommandTest extends CommandTestCase<DeleteUserCommand> {
|
||||
@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);
|
||||
verifyNoInteractions(connection);
|
||||
@@ -59,9 +61,10 @@ public class DeleteUserCommandTest extends CommandTestCase<DeleteUserCommand> {
|
||||
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();
|
||||
assertThat(DatabaseHelper.loadByKeyIfPresent(key)).isEmpty();
|
||||
verify(connection)
|
||||
.sendPostRequest(
|
||||
UpdateUserGroupAction.PATH,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+7
-8
@@ -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")
|
||||
|
||||
+2
@@ -104,6 +104,8 @@ public class WhoisRegistrarFieldsActionTest {
|
||||
ImmutableMap.of(
|
||||
"whoisServer",
|
||||
"whois.nic.google",
|
||||
"icannReferralEmail",
|
||||
"lol@sloth.test",
|
||||
"phoneNumber",
|
||||
"+1.4155552671",
|
||||
"faxNumber",
|
||||
|
||||
@@ -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>
|
||||
@@ -261,11 +261,11 @@ td.section {
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="property_name">generated on</td>
|
||||
<td class="property_value">2024-07-31 14:38:11</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">V176__drop_login_email_address_column_from_registrar_poc.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-31 14:38:11</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>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -174,3 +174,5 @@ 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 "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,
|
||||
|
||||
@@ -1316,7 +1316,6 @@ CREATE TABLE public."TmchCrl" (
|
||||
--
|
||||
|
||||
CREATE TABLE public."User" (
|
||||
id bigint,
|
||||
email_address text NOT NULL,
|
||||
registry_lock_password_hash text,
|
||||
registry_lock_password_salt text,
|
||||
@@ -1339,7 +1338,6 @@ CREATE TABLE public."UserUpdateHistory" (
|
||||
history_request_body text,
|
||||
history_type text NOT NULL,
|
||||
history_url text NOT NULL,
|
||||
user_id bigint,
|
||||
email_address text NOT NULL,
|
||||
registry_lock_password_hash text,
|
||||
registry_lock_password_salt text,
|
||||
@@ -1352,25 +1350,6 @@ CREATE TABLE public."UserUpdateHistory" (
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: User_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public."User_id_seq"
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: User_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public."User_id_seq" OWNED BY public."User".id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: project_wide_unique_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
@@ -1460,13 +1439,6 @@ ALTER TABLE ONLY public."SignedMarkRevocationList" ALTER COLUMN revision_id SET
|
||||
ALTER TABLE ONLY public."Spec11ThreatMatch" ALTER COLUMN id SET DEFAULT nextval('public."SafeBrowsingThreat_id_seq"'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: User id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."User" ALTER COLUMN id SET DEFAULT nextval('public."User_id_seq"'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: AllocationToken AllocationToken_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
@@ -31,12 +31,16 @@ do
|
||||
echo "Updating cluster ${parts[0]} in location ${parts[1]}..."
|
||||
gcloud container clusters get-credentials "${parts[0]}" \
|
||||
--project "${project}" --location "${parts[1]}"
|
||||
sed s/GCP_PROJECT/${project}/g "./kubernetes/nomulus-deployment.yaml" | \
|
||||
sed s/ENVIRONMENT/${environment}/g | \
|
||||
sed s/GCP_PROJECT/"${project}"/g "./kubernetes/nomulus-deployment.yaml" | \
|
||||
sed s/ENVIRONMENT/"${environment}"/g | \
|
||||
kubectl apply -f -
|
||||
kubectl apply -f "./kubernetes/nomulus-service.yaml"
|
||||
#kubectl apply -f "./kubernetes/nomulus-gateway.yaml"
|
||||
# Kills all running pods, new pods created will be pulling the new image.
|
||||
kubectl delete pods --all
|
||||
done < <(gcloud container clusters list --project ${project} | grep nomulus)
|
||||
# The multi-cluster gateway is only deployed to one cluster (the one in the US).
|
||||
if [[ "${parts[1]}" == us-* ]]
|
||||
then
|
||||
kubectl apply -f "./kubernetes/nomulus-gateway.yaml"
|
||||
fi
|
||||
done < <(gcloud container clusters list --project "${project}" | grep nomulus)
|
||||
kubectl config use-context "$current_context"
|
||||
|
||||
@@ -28,4 +28,19 @@ spec:
|
||||
kind: ServiceImport
|
||||
name: nomulus
|
||||
port: 80
|
||||
---
|
||||
apiVersion: networking.gke.io/v1
|
||||
kind: HealthCheckPolicy
|
||||
metadata:
|
||||
name: nomulus
|
||||
spec:
|
||||
default:
|
||||
config:
|
||||
type: HTTP
|
||||
httpHealthCheck:
|
||||
requestPath: /healthz/
|
||||
targetRef:
|
||||
group: net.gke.io
|
||||
kind: ServiceImport
|
||||
name: nomulus
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ spec:
|
||||
- port: 700
|
||||
targetPort: epp
|
||||
name: epp
|
||||
#---
|
||||
#kind: ServiceExport
|
||||
#apiVersion: net.gke.io/v1
|
||||
#metadata:
|
||||
# name: nomulus
|
||||
---
|
||||
kind: ServiceExport
|
||||
apiVersion: net.gke.io/v1
|
||||
metadata:
|
||||
name: nomulus
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<title>Health Check</title>
|
||||
<body>Health check successful.</body>
|
||||
</html>
|
||||
@@ -77,6 +77,8 @@ import org.joda.time.DateTime;
|
||||
@SuppressWarnings("FutureReturnValueIgnored")
|
||||
public class EppClient implements Runnable {
|
||||
|
||||
// TODO(b/354014191): Add loadtest handling for other EPP flows
|
||||
|
||||
static {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
}
|
||||
@@ -164,8 +166,9 @@ public class EppClient implements Runnable {
|
||||
|
||||
@Parameter(
|
||||
names = {"--tld"},
|
||||
description = "TLD to create domains on.")
|
||||
private String tld = "test";
|
||||
description = "TLD to create domains on.",
|
||||
required = true)
|
||||
private String tld = "loadtest";
|
||||
|
||||
@Parameter(
|
||||
names = {"--force_terminate", "-ft"},
|
||||
@@ -193,14 +196,17 @@ public class EppClient implements Runnable {
|
||||
ImmutableList.Builder<String> templatesList = ImmutableList.builder();
|
||||
ImmutableList.Builder<String> inputList = ImmutableList.builder();
|
||||
templatesList.add(readStringFromFile(LOGIN_FILE));
|
||||
String randomContactString = generateRandomString(5);
|
||||
if (domainCreates > 0) {
|
||||
templatesList.add(
|
||||
readStringFromFile(CONTACT_CREATE_FILE)
|
||||
.replace("@@RANDOM_CONTACT@@", randomContactString));
|
||||
}
|
||||
for (int i = 0; i < domainCreates; i++) {
|
||||
String randomString = generateRandomString(5);
|
||||
templatesList.add(
|
||||
readStringFromFile(CONTACT_CREATE_FILE)
|
||||
.replace("@@REPEAT_NUMBER@@", String.valueOf(i))
|
||||
.replace("@@RANDOM@@", randomString));
|
||||
templatesList.add(
|
||||
readStringFromFile(DOMAIN_CREATE_FILE)
|
||||
.replace("@@RANDOM_CONTACT@@", randomContactString)
|
||||
.replace("@@REPEAT_NUMBER@@", String.valueOf(i))
|
||||
.replace("@@RANDOM@@", randomString));
|
||||
}
|
||||
@@ -329,9 +335,14 @@ public class EppClient implements Runnable {
|
||||
|
||||
List<ChannelFuture> channelFutures = new ArrayList<>();
|
||||
|
||||
// Three requests: hello (from the proxy), login and logout plus additional configured EPP
|
||||
// requests.
|
||||
int requestPerConnection = 3 + (domainCreates * 2);
|
||||
// Three requests: hello (from the proxy), login and logout
|
||||
int requestsPerConnection = 3;
|
||||
|
||||
// If testing domain creates, add the number of domain creates per connection plus the one
|
||||
// contact created for each connection
|
||||
if (domainCreates > 0) {
|
||||
requestsPerConnection += domainCreates + 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < connections; i++) {
|
||||
bootstrap.attr(CHANNEL_NUMBER, i);
|
||||
@@ -347,6 +358,11 @@ public class EppClient implements Runnable {
|
||||
}
|
||||
|
||||
LinkedHashSet<Integer> killedConnections = new LinkedHashSet<>();
|
||||
LinkedHashSet<Integer> incompleteConnections = new LinkedHashSet<>();
|
||||
List<Long> requestDurations = new ArrayList<>();
|
||||
ZonedDateTime startTime = null;
|
||||
ZonedDateTime endTime = null;
|
||||
int failedRequests = 0;
|
||||
|
||||
// Wait for all channels to close.
|
||||
for (ChannelFuture channelFuture : channelFutures) {
|
||||
@@ -365,10 +381,47 @@ public class EppClient implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
for (ChannelFuture channelFuture : channelFutures) {
|
||||
Channel channel = channelFuture.channel();
|
||||
int channelNumber = channel.attr(CHANNEL_NUMBER).get();
|
||||
int responsesReceived = channel.attr(RESPONSE_RECEIVED).get().size();
|
||||
for (int i = 0; i < responsesReceived; i++) {
|
||||
requestDurations.add(
|
||||
Duration.between(
|
||||
channel.attr(REQUEST_SENT).get().get(i),
|
||||
channel.attr(RESPONSE_RECEIVED).get().get(i))
|
||||
.toMillis());
|
||||
}
|
||||
if (responsesReceived != requestsPerConnection) {
|
||||
incompleteConnections.add(channelNumber);
|
||||
failedRequests += (requestsPerConnection - channel.attr(REQUEST_SENT).get().size());
|
||||
}
|
||||
if (responsesReceived > 0) {
|
||||
startTime = updateStartTime(channelFutures, channelNumber, startTime);
|
||||
endTime = updateEndTime(channelFutures, channelNumber, endTime);
|
||||
}
|
||||
}
|
||||
|
||||
if (!incompleteConnections.isEmpty()) {
|
||||
System.out.printf("%d incomplete connections: ", incompleteConnections.size());
|
||||
for (int channelNumber : incompleteConnections) {
|
||||
System.out.printf("Channel %d not finished\n", channelNumber);
|
||||
}
|
||||
System.out.print("\n");
|
||||
}
|
||||
|
||||
System.out.println();
|
||||
System.out.println("====== SUMMARY ======");
|
||||
System.out.printf("Number of connections: %d\n", connections);
|
||||
System.out.printf("Number of requests per connection: %d\n", requestPerConnection);
|
||||
System.out.printf("Number of requests per connection: %d\n", requestsPerConnection);
|
||||
if (startTime != null && endTime != null) {
|
||||
System.out.printf(
|
||||
"Average Response QPS: %.2f\n",
|
||||
(double) requestDurations.size()
|
||||
* 1000.0
|
||||
/ Duration.between(startTime, endTime).toMillis());
|
||||
}
|
||||
System.out.printf("Number of incomplete connections: %d\n", incompleteConnections.size());
|
||||
if (!killedConnections.isEmpty()) {
|
||||
System.out.printf("Force killed connections (%d): ", killedConnections.size());
|
||||
for (int channelNumber : killedConnections) {
|
||||
@@ -376,6 +429,7 @@ public class EppClient implements Runnable {
|
||||
}
|
||||
System.out.print("\n");
|
||||
}
|
||||
System.out.printf("Number of Failed Requests: %d\n", failedRequests);
|
||||
|
||||
eventLoopGroup.shutdownGracefully();
|
||||
|
||||
@@ -388,4 +442,25 @@ public class EppClient implements Runnable {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private ZonedDateTime updateStartTime(
|
||||
List<ChannelFuture> channelFutures, int channelNumber, ZonedDateTime startTime) {
|
||||
ZonedDateTime channelStartTime =
|
||||
channelFutures.get(channelNumber).channel().attr(REQUEST_SENT).get().getFirst();
|
||||
if (startTime == null || startTime.isAfter(channelStartTime)) {
|
||||
return channelStartTime;
|
||||
}
|
||||
return startTime;
|
||||
}
|
||||
|
||||
private ZonedDateTime updateEndTime(
|
||||
List<ChannelFuture> channelFutures, int channelNumber, ZonedDateTime endTime) {
|
||||
ZonedDateTime channelEndTime =
|
||||
channelFutures.get(channelNumber).channel().attr(RESPONSE_RECEIVED).get().getLast();
|
||||
|
||||
if (endTime == null || endTime.isBefore(channelEndTime)) {
|
||||
return channelEndTime;
|
||||
}
|
||||
return endTime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<create>
|
||||
<contact:create
|
||||
xmlns:contact="urn:ietf:params:xml:ns:contact-1.0">
|
||||
<contact:id>@@RANDOM@@-@@CHANNEL_NUMBER@@-@@REPEAT_NUMBER@@</contact:id>
|
||||
<contact:id>@@RANDOM_CONTACT@@-@@CHANNEL_NUMBER@@</contact:id>
|
||||
<contact:postalInfo type="int">
|
||||
<contact:name>John Doe</contact:name>
|
||||
<contact:org>Example, Inc.</contact:org>
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
<domain:ns>
|
||||
<domain:hostObj>ns1.domain.com</domain:hostObj>
|
||||
</domain:ns>
|
||||
<domain:registrant>@@RANDOM@@-@@CHANNEL_NUMBER@@-@@REPEAT_NUMBER@@</domain:registrant>
|
||||
<domain:contact type="admin">@@RANDOM@@-@@CHANNEL_NUMBER@@-@@REPEAT_NUMBER@@</domain:contact>
|
||||
<domain:contact type="tech">@@RANDOM@@-@@CHANNEL_NUMBER@@-@@REPEAT_NUMBER@@</domain:contact>
|
||||
<domain:registrant>@@RANDOM_CONTACT@@-@@CHANNEL_NUMBER@@</domain:registrant>
|
||||
<domain:contact type="admin">@@RANDOM_CONTACT@@-@@CHANNEL_NUMBER@@</domain:contact>
|
||||
<domain:contact type="tech">@@RANDOM_CONTACT@@-@@CHANNEL_NUMBER@@</domain:contact>
|
||||
<domain:authInfo>
|
||||
<domain:pw>somepassword</domain:pw>
|
||||
</domain:authInfo>
|
||||
|
||||
Reference in New Issue
Block a user