mirror of
https://github.com/google/nomulus.git
synced 2025-07-24 19:48:32 +02:00
Add console registrars screen API support to /console-api/registrars endpoint (#2095)
This commit is contained in:
parent
68d35d2d95
commit
ec9a220bc3
13 changed files with 403 additions and 131 deletions
|
@ -0,0 +1,41 @@
|
||||||
|
// Copyright 2023 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.adapters;
|
||||||
|
|
||||||
|
import com.google.gson.TypeAdapter;
|
||||||
|
import com.google.gson.stream.JsonReader;
|
||||||
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
import google.registry.model.adapters.CurrencyUnitAdapter.UnknownCurrencyException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.joda.money.CurrencyUnit;
|
||||||
|
|
||||||
|
public class CurrencyJsonAdapter extends TypeAdapter<CurrencyUnit> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(JsonWriter out, CurrencyUnit value) throws IOException {
|
||||||
|
String currency = CurrencyUnitAdapter.convertFromCurrency(value);
|
||||||
|
out.value(currency);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CurrencyUnit read(JsonReader in) throws IOException {
|
||||||
|
String currency = in.nextString();
|
||||||
|
try {
|
||||||
|
return CurrencyUnitAdapter.convertFromString(currency);
|
||||||
|
} catch (UnknownCurrencyException e) {
|
||||||
|
throw new IOException("Unknown currency");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
|
// Copyright 2023 The Nomulus Authors. All Rights Reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -22,9 +22,7 @@ import org.joda.money.CurrencyUnit;
|
||||||
/** Adapter to use Joda {@link CurrencyUnit} when marshalling strings. */
|
/** Adapter to use Joda {@link CurrencyUnit} when marshalling strings. */
|
||||||
public class CurrencyUnitAdapter extends XmlAdapter<String, CurrencyUnit> {
|
public class CurrencyUnitAdapter extends XmlAdapter<String, CurrencyUnit> {
|
||||||
|
|
||||||
/** Parses a string into a {@link CurrencyUnit} object. */
|
public static CurrencyUnit convertFromString(String currency) throws UnknownCurrencyException {
|
||||||
@Override
|
|
||||||
public CurrencyUnit unmarshal(String currency) throws UnknownCurrencyException {
|
|
||||||
try {
|
try {
|
||||||
return CurrencyUnit.of(nullToEmpty(currency).trim());
|
return CurrencyUnit.of(nullToEmpty(currency).trim());
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
|
@ -32,10 +30,20 @@ public class CurrencyUnitAdapter extends XmlAdapter<String, CurrencyUnit> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String convertFromCurrency(CurrencyUnit currency) {
|
||||||
|
return currency == null ? null : currency.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Parses a string into a {@link CurrencyUnit} object. */
|
||||||
|
@Override
|
||||||
|
public CurrencyUnit unmarshal(String currency) throws UnknownCurrencyException {
|
||||||
|
return convertFromString(currency);
|
||||||
|
}
|
||||||
|
|
||||||
/** Converts {@link CurrencyUnit} to a string. */
|
/** Converts {@link CurrencyUnit} to a string. */
|
||||||
@Override
|
@Override
|
||||||
public String marshal(CurrencyUnit currency) {
|
public String marshal(CurrencyUnit currency) {
|
||||||
return currency == null ? null : currency.toString();
|
return convertFromCurrency(currency);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Exception to throw when failing to parse a currency. */
|
/** Exception to throw when failing to parse a currency. */
|
||||||
|
|
|
@ -20,6 +20,7 @@ import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
import google.registry.model.Buildable;
|
import google.registry.model.Buildable;
|
||||||
import google.registry.model.ImmutableObject;
|
import google.registry.model.ImmutableObject;
|
||||||
import google.registry.model.JsonMapBuilder;
|
import google.registry.model.JsonMapBuilder;
|
||||||
|
@ -87,6 +88,7 @@ public class Address extends ImmutableObject implements Jsonifiable, UnsafeSeria
|
||||||
*/
|
*/
|
||||||
@XmlJavaTypeAdapter(NormalizedStringAdapter.class)
|
@XmlJavaTypeAdapter(NormalizedStringAdapter.class)
|
||||||
@Transient
|
@Transient
|
||||||
|
@Expose
|
||||||
protected List<String> street;
|
protected List<String> street;
|
||||||
|
|
||||||
@XmlTransient @IgnoredInDiffableMap protected String streetLine1;
|
@XmlTransient @IgnoredInDiffableMap protected String streetLine1;
|
||||||
|
@ -96,18 +98,22 @@ public class Address extends ImmutableObject implements Jsonifiable, UnsafeSeria
|
||||||
@XmlTransient @IgnoredInDiffableMap protected String streetLine3;
|
@XmlTransient @IgnoredInDiffableMap protected String streetLine3;
|
||||||
|
|
||||||
@XmlJavaTypeAdapter(NormalizedStringAdapter.class)
|
@XmlJavaTypeAdapter(NormalizedStringAdapter.class)
|
||||||
|
@Expose
|
||||||
protected String city;
|
protected String city;
|
||||||
|
|
||||||
@XmlElement(name = "sp")
|
@XmlElement(name = "sp")
|
||||||
@XmlJavaTypeAdapter(NormalizedStringAdapter.class)
|
@XmlJavaTypeAdapter(NormalizedStringAdapter.class)
|
||||||
|
@Expose
|
||||||
protected String state;
|
protected String state;
|
||||||
|
|
||||||
@XmlElement(name = "pc")
|
@XmlElement(name = "pc")
|
||||||
@XmlJavaTypeAdapter(CollapsedStringAdapter.class)
|
@XmlJavaTypeAdapter(CollapsedStringAdapter.class)
|
||||||
|
@Expose
|
||||||
protected String zip;
|
protected String zip;
|
||||||
|
|
||||||
@XmlElement(name = "cc")
|
@XmlElement(name = "cc")
|
||||||
@XmlJavaTypeAdapter(CollapsedStringAdapter.class)
|
@XmlJavaTypeAdapter(CollapsedStringAdapter.class)
|
||||||
|
@Expose
|
||||||
protected String countryCode;
|
protected String countryCode;
|
||||||
|
|
||||||
public ImmutableList<String> getStreet() {
|
public ImmutableList<String> getStreet() {
|
||||||
|
|
|
@ -211,6 +211,7 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
|
||||||
*/
|
*/
|
||||||
@Id
|
@Id
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
|
@Expose
|
||||||
String registrarId;
|
String registrarId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -224,6 +225,7 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
|
||||||
* @see <a href="http://www.icann.org/registrar-reports/accredited-list.html">ICANN-Accredited
|
* @see <a href="http://www.icann.org/registrar-reports/accredited-list.html">ICANN-Accredited
|
||||||
* Registrars</a>
|
* Registrars</a>
|
||||||
*/
|
*/
|
||||||
|
@Expose
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
String registrarName;
|
String registrarName;
|
||||||
|
|
||||||
|
@ -237,7 +239,7 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
|
||||||
State state;
|
State state;
|
||||||
|
|
||||||
/** The set of TLDs which this registrar is allowed to access. */
|
/** The set of TLDs which this registrar is allowed to access. */
|
||||||
Set<String> allowedTlds;
|
@Expose Set<String> allowedTlds;
|
||||||
|
|
||||||
/** Host name of WHOIS server. */
|
/** Host name of WHOIS server. */
|
||||||
String whoisServer;
|
String whoisServer;
|
||||||
|
@ -287,6 +289,7 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
|
||||||
* unrestricted UTF-8.
|
* unrestricted UTF-8.
|
||||||
*/
|
*/
|
||||||
@Embedded
|
@Embedded
|
||||||
|
@Expose
|
||||||
@AttributeOverrides({
|
@AttributeOverrides({
|
||||||
@AttributeOverride(
|
@AttributeOverride(
|
||||||
name = "streetLine1",
|
name = "streetLine1",
|
||||||
|
@ -329,7 +332,7 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
|
||||||
String faxNumber;
|
String faxNumber;
|
||||||
|
|
||||||
/** Email address. */
|
/** Email address. */
|
||||||
String emailAddress;
|
@Expose String emailAddress;
|
||||||
|
|
||||||
// External IDs.
|
// External IDs.
|
||||||
|
|
||||||
|
@ -345,7 +348,7 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
|
||||||
* @see <a href="http://www.iana.org/assignments/registrar-ids/registrar-ids.txt">Registrar
|
* @see <a href="http://www.iana.org/assignments/registrar-ids/registrar-ids.txt">Registrar
|
||||||
* IDs</a>
|
* IDs</a>
|
||||||
*/
|
*/
|
||||||
@Nullable Long ianaIdentifier;
|
@Expose @Nullable Long ianaIdentifier;
|
||||||
|
|
||||||
/** Purchase Order number used for invoices in external billing system, if applicable. */
|
/** Purchase Order number used for invoices in external billing system, if applicable. */
|
||||||
@Nullable String poNumber;
|
@Nullable String poNumber;
|
||||||
|
@ -358,7 +361,7 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
|
||||||
* accessed by {@link #getBillingAccountMap}, a sorted map is returned to guarantee deterministic
|
* accessed by {@link #getBillingAccountMap}, a sorted map is returned to guarantee deterministic
|
||||||
* behavior when serializing the map, for display purpose for instance.
|
* behavior when serializing the map, for display purpose for instance.
|
||||||
*/
|
*/
|
||||||
@Nullable Map<CurrencyUnit, String> billingAccountMap;
|
@Expose @Nullable Map<CurrencyUnit, String> billingAccountMap;
|
||||||
|
|
||||||
/** URL of registrar's website. */
|
/** URL of registrar's website. */
|
||||||
String url;
|
String url;
|
||||||
|
@ -369,10 +372,10 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
|
||||||
* <p>This value is specified in the initial registrar contact. It can't be edited in the web GUI,
|
* <p>This value is specified in the initial registrar contact. It can't be edited in the web GUI,
|
||||||
* and it must be specified when the registrar account is created.
|
* and it must be specified when the registrar account is created.
|
||||||
*/
|
*/
|
||||||
String icannReferralEmail;
|
@Expose String icannReferralEmail;
|
||||||
|
|
||||||
/** Id of the folder in drive used to publish information for this registrar. */
|
/** Id of the folder in drive used to publish information for this registrar. */
|
||||||
String driveFolderId;
|
@Expose String driveFolderId;
|
||||||
|
|
||||||
// Metadata.
|
// Metadata.
|
||||||
|
|
||||||
|
@ -400,7 +403,7 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
|
||||||
boolean contactsRequireSyncing = true;
|
boolean contactsRequireSyncing = true;
|
||||||
|
|
||||||
/** Whether or not registry lock is allowed for this registrar. */
|
/** Whether or not registry lock is allowed for this registrar. */
|
||||||
boolean registryLockAllowed = false;
|
@Expose boolean registryLockAllowed = false;
|
||||||
|
|
||||||
public String getRegistrarId() {
|
public String getRegistrarId() {
|
||||||
return registrarId;
|
return registrarId;
|
||||||
|
|
|
@ -31,21 +31,28 @@ import com.google.common.io.ByteStreams;
|
||||||
import com.google.common.io.CharStreams;
|
import com.google.common.io.CharStreams;
|
||||||
import com.google.common.net.MediaType;
|
import com.google.common.net.MediaType;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.protobuf.ByteString;
|
import com.google.protobuf.ByteString;
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
import dagger.Provides;
|
import dagger.Provides;
|
||||||
|
import google.registry.model.adapters.CurrencyJsonAdapter;
|
||||||
import google.registry.request.HttpException.BadRequestException;
|
import google.registry.request.HttpException.BadRequestException;
|
||||||
import google.registry.request.HttpException.UnsupportedMediaTypeException;
|
import google.registry.request.HttpException.UnsupportedMediaTypeException;
|
||||||
import google.registry.request.auth.AuthResult;
|
import google.registry.request.auth.AuthResult;
|
||||||
import google.registry.request.lock.LockHandler;
|
import google.registry.request.lock.LockHandler;
|
||||||
import google.registry.request.lock.LockHandlerImpl;
|
import google.registry.request.lock.LockHandlerImpl;
|
||||||
|
import google.registry.util.CidrAddressBlock;
|
||||||
|
import google.registry.util.CidrAddressBlock.CidrAddressBlockAdapter;
|
||||||
|
import google.registry.util.DateTimeTypeAdapter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
|
import org.joda.money.CurrencyUnit;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
import org.json.simple.JSONValue;
|
import org.json.simple.JSONValue;
|
||||||
import org.json.simple.parser.ParseException;
|
import org.json.simple.parser.ParseException;
|
||||||
|
|
||||||
|
@ -69,6 +76,18 @@ public final class RequestModule {
|
||||||
this.authResult = authResult;
|
this.authResult = authResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequestScope
|
||||||
|
@VisibleForTesting
|
||||||
|
@Provides
|
||||||
|
public static Gson provideGson() {
|
||||||
|
return new GsonBuilder()
|
||||||
|
.registerTypeAdapter(DateTime.class, new DateTimeTypeAdapter())
|
||||||
|
.registerTypeAdapter(CidrAddressBlock.class, new CidrAddressBlockAdapter())
|
||||||
|
.registerTypeAdapter(CurrencyUnit.class, new CurrencyJsonAdapter())
|
||||||
|
.excludeFieldsWithoutExposeAnnotation()
|
||||||
|
.create();
|
||||||
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Parameter(RequestParameters.PARAM_TLD)
|
@Parameter(RequestParameters.PARAM_TLD)
|
||||||
static String provideTld(HttpServletRequest req) {
|
static String provideTld(HttpServletRequest req) {
|
||||||
|
|
|
@ -14,7 +14,11 @@
|
||||||
|
|
||||||
package google.registry.ui.server.console;
|
package google.registry.ui.server.console;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||||
|
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||||
import static google.registry.request.Action.Method.GET;
|
import static google.registry.request.Action.Method.GET;
|
||||||
|
import static google.registry.request.Action.Method.POST;
|
||||||
|
|
||||||
import com.google.api.client.http.HttpStatusCodes;
|
import com.google.api.client.http.HttpStatusCodes;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
@ -23,46 +27,155 @@ import com.google.gson.Gson;
|
||||||
import google.registry.model.console.ConsolePermission;
|
import google.registry.model.console.ConsolePermission;
|
||||||
import google.registry.model.console.User;
|
import google.registry.model.console.User;
|
||||||
import google.registry.model.registrar.Registrar;
|
import google.registry.model.registrar.Registrar;
|
||||||
|
import google.registry.model.registrar.Registrar.State;
|
||||||
|
import google.registry.model.registrar.RegistrarPoc;
|
||||||
import google.registry.request.Action;
|
import google.registry.request.Action;
|
||||||
|
import google.registry.request.Parameter;
|
||||||
import google.registry.request.Response;
|
import google.registry.request.Response;
|
||||||
import google.registry.request.auth.Auth;
|
import google.registry.request.auth.Auth;
|
||||||
import google.registry.request.auth.AuthResult;
|
import google.registry.request.auth.AuthResult;
|
||||||
import google.registry.ui.server.registrar.JsonGetAction;
|
import google.registry.ui.server.registrar.JsonGetAction;
|
||||||
|
import google.registry.util.StringGenerator;
|
||||||
|
import java.util.Optional;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
@Action(
|
@Action(
|
||||||
service = Action.Service.DEFAULT,
|
service = Action.Service.DEFAULT,
|
||||||
path = RegistrarsAction.PATH,
|
path = RegistrarsAction.PATH,
|
||||||
method = {GET},
|
method = {GET, POST},
|
||||||
auth = Auth.AUTH_PUBLIC_LOGGED_IN)
|
auth = Auth.AUTH_PUBLIC_LOGGED_IN)
|
||||||
public class RegistrarsAction implements JsonGetAction {
|
public class RegistrarsAction implements JsonGetAction {
|
||||||
|
private static final int PASSWORD_LENGTH = 16;
|
||||||
|
private static final int PASSCODE_LENGTH = 5;
|
||||||
static final String PATH = "/console-api/registrars";
|
static final String PATH = "/console-api/registrars";
|
||||||
|
|
||||||
private final AuthResult authResult;
|
private final AuthResult authResult;
|
||||||
private final Response response;
|
private final Response response;
|
||||||
private final Gson gson;
|
private final Gson gson;
|
||||||
|
private final HttpServletRequest req;
|
||||||
|
private Optional<Registrar> registrar;
|
||||||
|
private StringGenerator passwordGenerator;
|
||||||
|
private StringGenerator passcodeGenerator;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public RegistrarsAction(AuthResult authResult, Response response, Gson gson) {
|
public RegistrarsAction(
|
||||||
|
HttpServletRequest req,
|
||||||
|
AuthResult authResult,
|
||||||
|
Response response,
|
||||||
|
Gson gson,
|
||||||
|
@Parameter("registrar") Optional<Registrar> registrar,
|
||||||
|
@Named("base58StringGenerator") StringGenerator passwordGenerator,
|
||||||
|
@Named("digitOnlyStringGenerator") StringGenerator passcodeGenerator) {
|
||||||
this.authResult = authResult;
|
this.authResult = authResult;
|
||||||
this.response = response;
|
this.response = response;
|
||||||
this.gson = gson;
|
this.gson = gson;
|
||||||
|
this.registrar = registrar;
|
||||||
|
this.req = req;
|
||||||
|
this.passcodeGenerator = passcodeGenerator;
|
||||||
|
this.passwordGenerator = passwordGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
User user = authResult.userAuthInfo().get().consoleUser().get();
|
User user = authResult.userAuthInfo().get().consoleUser().get();
|
||||||
|
if (req.getMethod().equals(GET.toString())) {
|
||||||
|
getHandler(user);
|
||||||
|
} else {
|
||||||
|
postHandler(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getHandler(User user) {
|
||||||
if (!user.getUserRoles().hasGlobalPermission(ConsolePermission.VIEW_REGISTRARS)) {
|
if (!user.getUserRoles().hasGlobalPermission(ConsolePermission.VIEW_REGISTRARS)) {
|
||||||
response.setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
response.setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ImmutableList<String> registrarIds =
|
ImmutableList<Registrar> registrars =
|
||||||
Streams.stream(Registrar.loadAllCached())
|
Streams.stream(Registrar.loadAllCached())
|
||||||
.filter(r -> r.getType() == Registrar.Type.REAL)
|
.filter(r -> r.getType() == Registrar.Type.REAL)
|
||||||
.map(Registrar::getRegistrarId)
|
|
||||||
.collect(ImmutableList.toImmutableList());
|
.collect(ImmutableList.toImmutableList());
|
||||||
|
|
||||||
response.setPayload(gson.toJson(registrarIds));
|
response.setPayload(gson.toJson(registrars));
|
||||||
response.setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
response.setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void postHandler(User user) {
|
||||||
|
if (!user.getUserRoles().isAdmin()) {
|
||||||
|
response.setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!registrar.isPresent()) {
|
||||||
|
response.setStatus(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||||
|
response.setPayload(gson.toJson("'registrar' parameter is not present"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Registrar registrarParam = registrar.get();
|
||||||
|
String errorMsg = "Missing value for %s";
|
||||||
|
try {
|
||||||
|
checkArgument(!isNullOrEmpty(registrarParam.getRegistrarId()), errorMsg, "registrarId");
|
||||||
|
checkArgument(!isNullOrEmpty(registrarParam.getRegistrarName()), errorMsg, "name");
|
||||||
|
checkArgument(!registrarParam.getBillingAccountMap().isEmpty(), errorMsg, "billingAccount");
|
||||||
|
checkArgument(registrarParam.getIanaIdentifier() != null, String.format(errorMsg, "ianaId"));
|
||||||
|
checkArgument(
|
||||||
|
!isNullOrEmpty(registrarParam.getIcannReferralEmail()), errorMsg, "referralEmail");
|
||||||
|
checkArgument(!isNullOrEmpty(registrarParam.getDriveFolderId()), errorMsg, "driveId");
|
||||||
|
checkArgument(!isNullOrEmpty(registrarParam.getEmailAddress()), errorMsg, "consoleUserEmail");
|
||||||
|
checkArgument(
|
||||||
|
registrarParam.getLocalizedAddress() != null
|
||||||
|
&& !isNullOrEmpty(registrarParam.getLocalizedAddress().getState())
|
||||||
|
&& !isNullOrEmpty(registrarParam.getLocalizedAddress().getCity())
|
||||||
|
&& !isNullOrEmpty(registrarParam.getLocalizedAddress().getZip())
|
||||||
|
&& !isNullOrEmpty(registrarParam.getLocalizedAddress().getCountryCode())
|
||||||
|
&& !registrarParam.getLocalizedAddress().getStreet().isEmpty(),
|
||||||
|
errorMsg,
|
||||||
|
"address");
|
||||||
|
|
||||||
|
String password = passwordGenerator.createString(PASSWORD_LENGTH);
|
||||||
|
String phonePasscode = passcodeGenerator.createString(PASSCODE_LENGTH);
|
||||||
|
|
||||||
|
Registrar registrar =
|
||||||
|
new Registrar.Builder()
|
||||||
|
.setRegistrarId(registrarParam.getRegistrarId())
|
||||||
|
.setRegistrarName(registrarParam.getRegistrarName())
|
||||||
|
.setBillingAccountMap(registrarParam.getBillingAccountMap())
|
||||||
|
.setIanaIdentifier(Long.valueOf(registrarParam.getIanaIdentifier()))
|
||||||
|
.setIcannReferralEmail(registrarParam.getIcannReferralEmail())
|
||||||
|
.setEmailAddress(registrarParam.getIcannReferralEmail())
|
||||||
|
.setDriveFolderId(registrarParam.getDriveFolderId())
|
||||||
|
.setType(Registrar.Type.REAL)
|
||||||
|
.setPassword(password)
|
||||||
|
.setPhonePasscode(phonePasscode)
|
||||||
|
.setState(State.PENDING)
|
||||||
|
.setLocalizedAddress(registrarParam.getLocalizedAddress())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
RegistrarPoc contact =
|
||||||
|
new RegistrarPoc.Builder()
|
||||||
|
.setRegistrar(registrar)
|
||||||
|
.setName(registrarParam.getEmailAddress())
|
||||||
|
.setEmailAddress(registrarParam.getEmailAddress())
|
||||||
|
.setLoginEmailAddress(registrarParam.getEmailAddress())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
tm().transact(
|
||||||
|
() -> {
|
||||||
|
checkArgument(
|
||||||
|
!Registrar.loadByRegistrarId(registrar.getRegistrarId()).isPresent(),
|
||||||
|
"Registrar with registrarId %s already exists",
|
||||||
|
registrar.getRegistrarId());
|
||||||
|
tm().putAll(registrar, contact);
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
response.setStatus(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||||
|
response.setPayload(gson.toJson(e.getMessage()));
|
||||||
|
} catch (Throwable e) {
|
||||||
|
response.setStatus(HttpStatusCodes.STATUS_CODE_SERVER_ERROR);
|
||||||
|
response.setPayload(gson.toJson(e.getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
package google.registry.ui.server.console.settings;
|
package google.registry.ui.server.console.settings;
|
||||||
|
|
||||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||||
import static google.registry.request.Action.Method.GET;
|
|
||||||
import static google.registry.request.Action.Method.POST;
|
import static google.registry.request.Action.Method.POST;
|
||||||
|
|
||||||
import avro.shaded.com.google.common.collect.ImmutableList;
|
import avro.shaded.com.google.common.collect.ImmutableList;
|
||||||
|
@ -36,28 +35,25 @@ import google.registry.request.auth.AuthenticatedRegistrarAccessor.RegistrarAcce
|
||||||
import google.registry.ui.server.registrar.JsonGetAction;
|
import google.registry.ui.server.registrar.JsonGetAction;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
@Action(
|
@Action(
|
||||||
service = Action.Service.DEFAULT,
|
service = Action.Service.DEFAULT,
|
||||||
path = SecurityAction.PATH,
|
path = SecurityAction.PATH,
|
||||||
method = {GET, POST},
|
method = {POST},
|
||||||
auth = Auth.AUTH_PUBLIC_LOGGED_IN)
|
auth = Auth.AUTH_PUBLIC_LOGGED_IN)
|
||||||
public class SecurityAction implements JsonGetAction {
|
public class SecurityAction implements JsonGetAction {
|
||||||
|
|
||||||
static final String PATH = "/console-api/settings/security";
|
static final String PATH = "/console-api/settings/security";
|
||||||
private final HttpServletRequest req;
|
|
||||||
private final AuthResult authResult;
|
private final AuthResult authResult;
|
||||||
private final Response response;
|
private final Response response;
|
||||||
private final Gson gson;
|
private final Gson gson;
|
||||||
private final String registrarId;
|
private final String registrarId;
|
||||||
private AuthenticatedRegistrarAccessor registrarAccessor;
|
private final AuthenticatedRegistrarAccessor registrarAccessor;
|
||||||
private Optional<Registrar> registrar;
|
private final Optional<Registrar> registrar;
|
||||||
private CertificateChecker certificateChecker;
|
private final CertificateChecker certificateChecker;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public SecurityAction(
|
public SecurityAction(
|
||||||
HttpServletRequest req,
|
|
||||||
AuthResult authResult,
|
AuthResult authResult,
|
||||||
Response response,
|
Response response,
|
||||||
Gson gson,
|
Gson gson,
|
||||||
|
@ -65,7 +61,6 @@ public class SecurityAction implements JsonGetAction {
|
||||||
AuthenticatedRegistrarAccessor registrarAccessor,
|
AuthenticatedRegistrarAccessor registrarAccessor,
|
||||||
@Parameter("registrarId") String registrarId,
|
@Parameter("registrarId") String registrarId,
|
||||||
@Parameter("registrar") Optional<Registrar> registrar) {
|
@Parameter("registrar") Optional<Registrar> registrar) {
|
||||||
this.req = req;
|
|
||||||
this.authResult = authResult;
|
this.authResult = authResult;
|
||||||
this.response = response;
|
this.response = response;
|
||||||
this.gson = gson;
|
this.gson = gson;
|
||||||
|
@ -77,25 +72,6 @@ public class SecurityAction implements JsonGetAction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (req.getMethod().equals(GET.toString())) {
|
|
||||||
getHandler();
|
|
||||||
} else {
|
|
||||||
postHandler();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getHandler() {
|
|
||||||
try {
|
|
||||||
Registrar registrar = registrarAccessor.getRegistrar(registrarId);
|
|
||||||
response.setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
|
||||||
response.setPayload(gson.toJson(registrar));
|
|
||||||
} catch (RegistrarAccessDeniedException e) {
|
|
||||||
response.setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
|
||||||
response.setPayload(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void postHandler() {
|
|
||||||
User user = authResult.userAuthInfo().get().consoleUser().get();
|
User user = authResult.userAuthInfo().get().consoleUser().get();
|
||||||
if (!user.getUserRoles().hasPermission(registrarId, ConsolePermission.EDIT_REGISTRAR_DETAILS)) {
|
if (!user.getUserRoles().hasPermission(registrarId, ConsolePermission.EDIT_REGISTRAR_DETAILS)) {
|
||||||
response.setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
response.setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
|
||||||
|
@ -153,17 +129,15 @@ public class SecurityAction implements JsonGetAction {
|
||||||
registrarParameter
|
registrarParameter
|
||||||
.getClientCertificate()
|
.getClientCertificate()
|
||||||
.ifPresent(
|
.ifPresent(
|
||||||
newClientCert -> {
|
newClientCert ->
|
||||||
updatedRegistrar.setClientCertificate(newClientCert, tm().getTransactionTime());
|
updatedRegistrar.setClientCertificate(newClientCert, tm().getTransactionTime()));
|
||||||
});
|
|
||||||
|
|
||||||
registrarParameter
|
registrarParameter
|
||||||
.getFailoverClientCertificate()
|
.getFailoverClientCertificate()
|
||||||
.ifPresent(
|
.ifPresent(
|
||||||
failoverCert -> {
|
failoverCert ->
|
||||||
updatedRegistrar.setFailoverClientCertificate(
|
updatedRegistrar.setFailoverClientCertificate(
|
||||||
failoverCert, tm().getTransactionTime());
|
failoverCert, tm().getTransactionTime()));
|
||||||
});
|
|
||||||
|
|
||||||
tm().put(updatedRegistrar.build());
|
tm().put(updatedRegistrar.build());
|
||||||
response.setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
response.setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
||||||
|
|
|
@ -25,12 +25,12 @@ import google.registry.model.console.RegistrarRole;
|
||||||
import google.registry.model.console.User;
|
import google.registry.model.console.User;
|
||||||
import google.registry.model.console.UserRoles;
|
import google.registry.model.console.UserRoles;
|
||||||
import google.registry.persistence.transaction.JpaTestExtensions;
|
import google.registry.persistence.transaction.JpaTestExtensions;
|
||||||
|
import google.registry.request.RequestModule;
|
||||||
import google.registry.request.auth.AuthResult;
|
import google.registry.request.auth.AuthResult;
|
||||||
import google.registry.request.auth.AuthSettings.AuthLevel;
|
import google.registry.request.auth.AuthSettings.AuthLevel;
|
||||||
import google.registry.request.auth.UserAuthInfo;
|
import google.registry.request.auth.UserAuthInfo;
|
||||||
import google.registry.testing.DatabaseHelper;
|
import google.registry.testing.DatabaseHelper;
|
||||||
import google.registry.testing.FakeResponse;
|
import google.registry.testing.FakeResponse;
|
||||||
import google.registry.util.UtilsModule;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
@ -38,7 +38,7 @@ import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
/** Tests for {@link google.registry.ui.server.console.ConsoleDomainGetAction}. */
|
/** Tests for {@link google.registry.ui.server.console.ConsoleDomainGetAction}. */
|
||||||
public class ConsoleDomainGetActionTest {
|
public class ConsoleDomainGetActionTest {
|
||||||
|
|
||||||
private static final Gson GSON = UtilsModule.provideGson();
|
private static final Gson GSON = RequestModule.provideGson();
|
||||||
private static final FakeResponse RESPONSE = new FakeResponse();
|
private static final FakeResponse RESPONSE = new FakeResponse();
|
||||||
|
|
||||||
@RegisterExtension
|
@RegisterExtension
|
||||||
|
|
|
@ -15,11 +15,17 @@
|
||||||
package google.registry.ui.server.console;
|
package google.registry.ui.server.console;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static google.registry.testing.DatabaseHelper.loadAllOf;
|
||||||
|
import static google.registry.testing.DatabaseHelper.loadRegistrar;
|
||||||
import static google.registry.testing.DatabaseHelper.persistNewRegistrar;
|
import static google.registry.testing.DatabaseHelper.persistNewRegistrar;
|
||||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||||
import static google.registry.testing.SqlHelper.saveRegistrar;
|
import static google.registry.testing.SqlHelper.saveRegistrar;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import com.google.api.client.http.HttpStatusCodes;
|
import com.google.api.client.http.HttpStatusCodes;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import google.registry.model.console.GlobalRole;
|
import google.registry.model.console.GlobalRole;
|
||||||
|
@ -27,21 +33,69 @@ import google.registry.model.console.RegistrarRole;
|
||||||
import google.registry.model.console.User;
|
import google.registry.model.console.User;
|
||||||
import google.registry.model.console.UserRoles;
|
import google.registry.model.console.UserRoles;
|
||||||
import google.registry.model.registrar.Registrar;
|
import google.registry.model.registrar.Registrar;
|
||||||
|
import google.registry.model.registrar.RegistrarPoc;
|
||||||
import google.registry.persistence.transaction.JpaTestExtensions;
|
import google.registry.persistence.transaction.JpaTestExtensions;
|
||||||
|
import google.registry.request.Action;
|
||||||
|
import google.registry.request.RequestModule;
|
||||||
import google.registry.request.auth.AuthResult;
|
import google.registry.request.auth.AuthResult;
|
||||||
import google.registry.request.auth.AuthSettings.AuthLevel;
|
import google.registry.request.auth.AuthSettings.AuthLevel;
|
||||||
import google.registry.request.auth.UserAuthInfo;
|
import google.registry.request.auth.UserAuthInfo;
|
||||||
|
import google.registry.testing.DeterministicStringGenerator;
|
||||||
import google.registry.testing.FakeResponse;
|
import google.registry.testing.FakeResponse;
|
||||||
import google.registry.util.UtilsModule;
|
import google.registry.ui.server.registrar.RegistrarConsoleModule;
|
||||||
|
import google.registry.util.StringGenerator;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
/** Tests for {@link google.registry.ui.server.console.RegistrarsAction}. */
|
/** Tests for {@link google.registry.ui.server.console.RegistrarsAction}. */
|
||||||
class RegistrarsActionTest {
|
class RegistrarsActionTest {
|
||||||
|
|
||||||
private static final Gson GSON = UtilsModule.provideGson();
|
private final HttpServletRequest request = mock(HttpServletRequest.class);
|
||||||
|
private static final Gson GSON = RequestModule.provideGson();
|
||||||
private FakeResponse response;
|
private FakeResponse response;
|
||||||
|
|
||||||
|
private StringGenerator passwordGenerator =
|
||||||
|
new DeterministicStringGenerator("abcdefghijklmnopqrstuvwxyz");
|
||||||
|
private StringGenerator passcodeGenerator = new DeterministicStringGenerator("314159265");
|
||||||
|
|
||||||
|
private ImmutableMap<String, String> userFriendlyKeysToRegistrarKeys =
|
||||||
|
ImmutableMap.of(
|
||||||
|
"registrarId", "registrarId",
|
||||||
|
"registrarName", "name",
|
||||||
|
"billingAccountMap", "billingAccount",
|
||||||
|
"ianaIdentifier", "ianaId",
|
||||||
|
"icannReferralEmail", "referralEmail",
|
||||||
|
"driveFolderId", "driveId",
|
||||||
|
"emailAddress", "consoleUserEmail",
|
||||||
|
"localizedAddress", "address");
|
||||||
|
|
||||||
|
private ImmutableMap<String, String> registrarParamMap =
|
||||||
|
ImmutableMap.of(
|
||||||
|
"registrarId",
|
||||||
|
"regIdTest",
|
||||||
|
"registrarName",
|
||||||
|
"name",
|
||||||
|
"billingAccountMap",
|
||||||
|
"{\"USD\": \"789\"}",
|
||||||
|
"ianaIdentifier",
|
||||||
|
"123",
|
||||||
|
"icannReferralEmail",
|
||||||
|
"cannReferralEmail@gmail.com",
|
||||||
|
"driveFolderId",
|
||||||
|
"testDriveId",
|
||||||
|
"emailAddress",
|
||||||
|
"testEmailAddress@gmail.com",
|
||||||
|
"localizedAddress",
|
||||||
|
"{ \"street\": [\"test street\"], \"city\": \"test city\", \"state\": \"test state\","
|
||||||
|
+ " \"zip\": \"00700\", \"countryCode\": \"US\" }");
|
||||||
|
|
||||||
@RegisterExtension
|
@RegisterExtension
|
||||||
final JpaTestExtensions.JpaIntegrationTestExtension jpa =
|
final JpaTestExtensions.JpaIntegrationTestExtension jpa =
|
||||||
new JpaTestExtensions.Builder().buildIntegrationTestExtension();
|
new JpaTestExtensions.Builder().buildIntegrationTestExtension();
|
||||||
|
@ -53,6 +107,7 @@ class RegistrarsActionTest {
|
||||||
persistResource(registrar);
|
persistResource(registrar);
|
||||||
RegistrarsAction action =
|
RegistrarsAction action =
|
||||||
createAction(
|
createAction(
|
||||||
|
Action.Method.GET,
|
||||||
AuthResult.create(
|
AuthResult.create(
|
||||||
AuthLevel.USER,
|
AuthLevel.USER,
|
||||||
UserAuthInfo.create(
|
UserAuthInfo.create(
|
||||||
|
@ -60,22 +115,98 @@ class RegistrarsActionTest {
|
||||||
new UserRoles.Builder().setGlobalRole(GlobalRole.SUPPORT_LEAD).build()))));
|
new UserRoles.Builder().setGlobalRole(GlobalRole.SUPPORT_LEAD).build()))));
|
||||||
action.run();
|
action.run();
|
||||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||||
assertThat(response.getPayload()).isEqualTo("[\"NewRegistrar\",\"TheRegistrar\"]");
|
String payload = response.getPayload();
|
||||||
|
assertThat(
|
||||||
|
ImmutableList.of("\"registrarId\":\"NewRegistrar\"", "\"registrarId\":\"TheRegistrar\"")
|
||||||
|
.stream()
|
||||||
|
.allMatch(s -> payload.contains(s)))
|
||||||
|
.isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testSuccess_getRegistrarIds() {
|
void testSuccess_getRegistrars() {
|
||||||
saveRegistrar("registrarId");
|
saveRegistrar("registrarId");
|
||||||
RegistrarsAction action =
|
RegistrarsAction action =
|
||||||
createAction(
|
createAction(
|
||||||
|
Action.Method.GET,
|
||||||
AuthResult.create(
|
AuthResult.create(
|
||||||
AuthLevel.USER,
|
AuthLevel.USER,
|
||||||
UserAuthInfo.create(
|
UserAuthInfo.create(
|
||||||
createUser(new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).build()))));
|
createUser(new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).build()))));
|
||||||
action.run();
|
action.run();
|
||||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||||
|
String payload = response.getPayload();
|
||||||
|
assertThat(
|
||||||
|
ImmutableList.of(
|
||||||
|
"\"registrarId\":\"NewRegistrar\"",
|
||||||
|
"\"registrarId\":\"TheRegistrar\"",
|
||||||
|
"\"registrarId\":\"registrarId\"")
|
||||||
|
.stream()
|
||||||
|
.allMatch(s -> payload.contains(s)))
|
||||||
|
.isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSuccess_createRegistrar() {
|
||||||
|
RegistrarsAction action =
|
||||||
|
createAction(
|
||||||
|
Action.Method.POST,
|
||||||
|
AuthResult.create(
|
||||||
|
AuthLevel.USER,
|
||||||
|
UserAuthInfo.create(createUser(new UserRoles.Builder().setIsAdmin(true).build()))));
|
||||||
|
action.run();
|
||||||
|
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
||||||
|
Registrar r = loadRegistrar("regIdTest");
|
||||||
|
assertThat(r).isNotNull();
|
||||||
|
assertThat(
|
||||||
|
loadAllOf(RegistrarPoc.class).stream()
|
||||||
|
.filter(rPOC -> rPOC.getEmailAddress().equals("testEmailAddress@gmail.com"))
|
||||||
|
.findAny()
|
||||||
|
.isPresent())
|
||||||
|
.isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFailure_createRegistrar_missingValue() {
|
||||||
|
ImmutableMap<String, String> copy = ImmutableMap.copyOf(registrarParamMap);
|
||||||
|
copy.keySet()
|
||||||
|
.forEach(
|
||||||
|
key -> {
|
||||||
|
registrarParamMap =
|
||||||
|
ImmutableMap.copyOf(
|
||||||
|
copy.entrySet().stream()
|
||||||
|
.filter(entry -> !entry.getKey().equals(key))
|
||||||
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
|
||||||
|
RegistrarsAction action =
|
||||||
|
createAction(
|
||||||
|
Action.Method.POST,
|
||||||
|
AuthResult.create(
|
||||||
|
AuthLevel.USER,
|
||||||
|
UserAuthInfo.create(
|
||||||
|
createUser(new UserRoles.Builder().setIsAdmin(true).build()))));
|
||||||
|
action.run();
|
||||||
|
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||||
|
assertThat(response.getPayload())
|
||||||
|
.isEqualTo(
|
||||||
|
GSON.toJson(
|
||||||
|
String.format(
|
||||||
|
"Missing value for %s", userFriendlyKeysToRegistrarKeys.get(key))));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFailure_createRegistrar_existingRegistrar() {
|
||||||
|
saveRegistrar("regIdTest");
|
||||||
|
RegistrarsAction action =
|
||||||
|
createAction(
|
||||||
|
Action.Method.POST,
|
||||||
|
AuthResult.create(
|
||||||
|
AuthLevel.USER,
|
||||||
|
UserAuthInfo.create(createUser(new UserRoles.Builder().setIsAdmin(true).build()))));
|
||||||
|
action.run();
|
||||||
|
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||||
assertThat(response.getPayload())
|
assertThat(response.getPayload())
|
||||||
.isEqualTo("[\"NewRegistrar\",\"TheRegistrar\",\"registrarId\"]");
|
.isEqualTo(GSON.toJson("Registrar with registrarId regIdTest already exists"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -83,6 +214,7 @@ class RegistrarsActionTest {
|
||||||
saveRegistrar("registrarId");
|
saveRegistrar("registrarId");
|
||||||
RegistrarsAction action =
|
RegistrarsAction action =
|
||||||
createAction(
|
createAction(
|
||||||
|
Action.Method.GET,
|
||||||
AuthResult.create(
|
AuthResult.create(
|
||||||
AuthLevel.USER,
|
AuthLevel.USER,
|
||||||
UserAuthInfo.create(
|
UserAuthInfo.create(
|
||||||
|
@ -105,8 +237,46 @@ class RegistrarsActionTest {
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private RegistrarsAction createAction(AuthResult authResult) {
|
private RegistrarsAction createAction(Action.Method method, AuthResult authResult) {
|
||||||
response = new FakeResponse();
|
response = new FakeResponse();
|
||||||
return new RegistrarsAction(authResult, response, GSON);
|
when(request.getMethod()).thenReturn(method.toString());
|
||||||
|
if (method.equals(Action.Method.GET)) {
|
||||||
|
return new RegistrarsAction(
|
||||||
|
request,
|
||||||
|
authResult,
|
||||||
|
response,
|
||||||
|
GSON,
|
||||||
|
Optional.ofNullable(null),
|
||||||
|
passwordGenerator,
|
||||||
|
passcodeGenerator);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
doReturn(
|
||||||
|
new BufferedReader(
|
||||||
|
new StringReader("{\"registrar\":" + registrarParamMap.toString() + "}")))
|
||||||
|
.when(request)
|
||||||
|
.getReader();
|
||||||
|
} catch (IOException e) {
|
||||||
|
return new RegistrarsAction(
|
||||||
|
request,
|
||||||
|
authResult,
|
||||||
|
response,
|
||||||
|
GSON,
|
||||||
|
Optional.ofNullable(null),
|
||||||
|
passwordGenerator,
|
||||||
|
passcodeGenerator);
|
||||||
|
}
|
||||||
|
Optional<Registrar> maybeRegistrar =
|
||||||
|
RegistrarConsoleModule.provideRegistrar(
|
||||||
|
GSON, RequestModule.provideJsonBody(request, GSON));
|
||||||
|
return new RegistrarsAction(
|
||||||
|
request,
|
||||||
|
authResult,
|
||||||
|
response,
|
||||||
|
GSON,
|
||||||
|
maybeRegistrar,
|
||||||
|
passwordGenerator,
|
||||||
|
passcodeGenerator);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,6 @@ import google.registry.request.auth.AuthSettings.AuthLevel;
|
||||||
import google.registry.request.auth.UserAuthInfo;
|
import google.registry.request.auth.UserAuthInfo;
|
||||||
import google.registry.testing.FakeResponse;
|
import google.registry.testing.FakeResponse;
|
||||||
import google.registry.ui.server.registrar.RegistrarConsoleModule;
|
import google.registry.ui.server.registrar.RegistrarConsoleModule;
|
||||||
import google.registry.util.UtilsModule;
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
@ -73,7 +72,7 @@ class ContactActionTest {
|
||||||
private Registrar testRegistrar;
|
private Registrar testRegistrar;
|
||||||
private final HttpServletRequest request = mock(HttpServletRequest.class);
|
private final HttpServletRequest request = mock(HttpServletRequest.class);
|
||||||
private RegistrarPoc testRegistrarPoc;
|
private RegistrarPoc testRegistrarPoc;
|
||||||
private static final Gson GSON = UtilsModule.provideGson();
|
private static final Gson GSON = RequestModule.provideGson();
|
||||||
private FakeResponse response;
|
private FakeResponse response;
|
||||||
|
|
||||||
@RegisterExtension
|
@RegisterExtension
|
||||||
|
|
|
@ -15,21 +15,17 @@
|
||||||
package google.registry.ui.server.console.settings;
|
package google.registry.ui.server.console.settings;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static google.registry.testing.CertificateSamples.SAMPLE_CERT;
|
|
||||||
import static google.registry.testing.CertificateSamples.SAMPLE_CERT2;
|
import static google.registry.testing.CertificateSamples.SAMPLE_CERT2;
|
||||||
import static google.registry.testing.DatabaseHelper.loadRegistrar;
|
import static google.registry.testing.DatabaseHelper.loadRegistrar;
|
||||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
|
||||||
import static google.registry.testing.SqlHelper.saveRegistrar;
|
import static google.registry.testing.SqlHelper.saveRegistrar;
|
||||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import com.google.api.client.http.HttpStatusCodes;
|
import com.google.api.client.http.HttpStatusCodes;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.ImmutableSetMultimap;
|
import com.google.common.collect.ImmutableSetMultimap;
|
||||||
import com.google.common.collect.ImmutableSortedMap;
|
import com.google.common.collect.ImmutableSortedMap;
|
||||||
import com.google.common.net.InetAddresses;
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import google.registry.flows.certs.CertificateChecker;
|
import google.registry.flows.certs.CertificateChecker;
|
||||||
import google.registry.model.console.GlobalRole;
|
import google.registry.model.console.GlobalRole;
|
||||||
|
@ -37,7 +33,6 @@ import google.registry.model.console.User;
|
||||||
import google.registry.model.console.UserRoles;
|
import google.registry.model.console.UserRoles;
|
||||||
import google.registry.model.registrar.Registrar;
|
import google.registry.model.registrar.Registrar;
|
||||||
import google.registry.persistence.transaction.JpaTestExtensions;
|
import google.registry.persistence.transaction.JpaTestExtensions;
|
||||||
import google.registry.request.Action;
|
|
||||||
import google.registry.request.RequestModule;
|
import google.registry.request.RequestModule;
|
||||||
import google.registry.request.auth.AuthResult;
|
import google.registry.request.auth.AuthResult;
|
||||||
import google.registry.request.auth.AuthSettings.AuthLevel;
|
import google.registry.request.auth.AuthSettings.AuthLevel;
|
||||||
|
@ -46,8 +41,6 @@ import google.registry.request.auth.UserAuthInfo;
|
||||||
import google.registry.testing.FakeClock;
|
import google.registry.testing.FakeClock;
|
||||||
import google.registry.testing.FakeResponse;
|
import google.registry.testing.FakeResponse;
|
||||||
import google.registry.ui.server.registrar.RegistrarConsoleModule;
|
import google.registry.ui.server.registrar.RegistrarConsoleModule;
|
||||||
import google.registry.util.CidrAddressBlock;
|
|
||||||
import google.registry.util.UtilsModule;
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
@ -66,7 +59,7 @@ class SecurityActionTest {
|
||||||
"{\"registrarId\": \"registrarId\", \"clientCertificate\": \"%s\","
|
"{\"registrarId\": \"registrarId\", \"clientCertificate\": \"%s\","
|
||||||
+ " \"ipAddressAllowList\": [\"192.168.1.1/32\"]}",
|
+ " \"ipAddressAllowList\": [\"192.168.1.1/32\"]}",
|
||||||
SAMPLE_CERT2);
|
SAMPLE_CERT2);
|
||||||
private static final Gson GSON = UtilsModule.provideGson();
|
private static final Gson GSON = RequestModule.provideGson();
|
||||||
private final HttpServletRequest request = mock(HttpServletRequest.class);
|
private final HttpServletRequest request = mock(HttpServletRequest.class);
|
||||||
private final FakeClock clock = new FakeClock();
|
private final FakeClock clock = new FakeClock();
|
||||||
private Registrar testRegistrar;
|
private Registrar testRegistrar;
|
||||||
|
@ -94,39 +87,11 @@ class SecurityActionTest {
|
||||||
testRegistrar = saveRegistrar("registrarId");
|
testRegistrar = saveRegistrar("registrarId");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSuccess_getRegistrarInfo() throws IOException {
|
|
||||||
persistResource(
|
|
||||||
testRegistrar
|
|
||||||
.asBuilder()
|
|
||||||
.setClientCertificate(SAMPLE_CERT, clock.nowUtc())
|
|
||||||
.setIpAddressAllowList(
|
|
||||||
ImmutableSet.of(
|
|
||||||
CidrAddressBlock.create(InetAddresses.forString("192.168.1.1"), 32),
|
|
||||||
CidrAddressBlock.create(InetAddresses.forString("2001:db8::1"), 128)))
|
|
||||||
.build());
|
|
||||||
SecurityAction action =
|
|
||||||
createAction(
|
|
||||||
Action.Method.GET,
|
|
||||||
AuthResult.create(
|
|
||||||
AuthLevel.USER,
|
|
||||||
UserAuthInfo.create(
|
|
||||||
createUser(new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).build()))),
|
|
||||||
testRegistrar.getRegistrarId());
|
|
||||||
action.run();
|
|
||||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK);
|
|
||||||
String payload = response.getPayload().replace("\\n", "").replace("\\u003d", "=");
|
|
||||||
assertThat(payload).contains(SAMPLE_CERT.replace("\n", ""));
|
|
||||||
assertThat(payload).contains("192.168.1.1/32");
|
|
||||||
assertThat(payload).contains("2001:db8:0:0:0:0:0:1/128");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testSuccess_postRegistrarInfo() throws IOException {
|
void testSuccess_postRegistrarInfo() throws IOException {
|
||||||
clock.setTo(DateTime.parse("2020-11-01T00:00:00Z"));
|
clock.setTo(DateTime.parse("2020-11-01T00:00:00Z"));
|
||||||
SecurityAction action =
|
SecurityAction action =
|
||||||
createAction(
|
createAction(
|
||||||
Action.Method.POST,
|
|
||||||
AuthResult.create(
|
AuthResult.create(
|
||||||
AuthLevel.USER,
|
AuthLevel.USER,
|
||||||
UserAuthInfo.create(
|
UserAuthInfo.create(
|
||||||
|
@ -149,20 +114,8 @@ class SecurityActionTest {
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private SecurityAction createAction(
|
private SecurityAction createAction(AuthResult authResult, String registrarId)
|
||||||
Action.Method method, AuthResult authResult, String registrarId) throws IOException {
|
throws IOException {
|
||||||
when(request.getMethod()).thenReturn(method.toString());
|
|
||||||
if (method.equals(Action.Method.GET)) {
|
|
||||||
return new SecurityAction(
|
|
||||||
request,
|
|
||||||
authResult,
|
|
||||||
response,
|
|
||||||
GSON,
|
|
||||||
certificateChecker,
|
|
||||||
registrarAccessor,
|
|
||||||
registrarId,
|
|
||||||
Optional.empty());
|
|
||||||
} else {
|
|
||||||
doReturn(new BufferedReader(new StringReader("{\"registrar\":" + jsonRegistrar1 + "}")))
|
doReturn(new BufferedReader(new StringReader("{\"registrar\":" + jsonRegistrar1 + "}")))
|
||||||
.when(request)
|
.when(request)
|
||||||
.getReader();
|
.getReader();
|
||||||
|
@ -170,7 +123,6 @@ class SecurityActionTest {
|
||||||
RegistrarConsoleModule.provideRegistrar(
|
RegistrarConsoleModule.provideRegistrar(
|
||||||
GSON, RequestModule.provideJsonBody(request, GSON));
|
GSON, RequestModule.provideJsonBody(request, GSON));
|
||||||
return new SecurityAction(
|
return new SecurityAction(
|
||||||
request,
|
|
||||||
authResult,
|
authResult,
|
||||||
response,
|
response,
|
||||||
GSON,
|
GSON,
|
||||||
|
@ -178,6 +130,6 @@ class SecurityActionTest {
|
||||||
registrarAccessor,
|
registrarAccessor,
|
||||||
registrarId,
|
registrarId,
|
||||||
maybeRegistrar);
|
maybeRegistrar);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
PATH CLASS METHODS OK AUTH_METHODS MIN USER_POLICY
|
PATH CLASS METHODS OK AUTH_METHODS MIN USER_POLICY
|
||||||
/_dr/epp EppTlsAction POST n API APP PUBLIC
|
/_dr/epp EppTlsAction POST n API APP PUBLIC
|
||||||
/console-api/domain ConsoleDomainGetAction GET n API,LEGACY USER PUBLIC
|
/console-api/domain ConsoleDomainGetAction GET n API,LEGACY USER PUBLIC
|
||||||
/console-api/registrars RegistrarsAction GET n API,LEGACY USER PUBLIC
|
/console-api/registrars RegistrarsAction GET,POST n API,LEGACY USER PUBLIC
|
||||||
/console-api/settings/contacts ContactAction GET,POST n API,LEGACY USER PUBLIC
|
/console-api/settings/contacts ContactAction GET,POST n API,LEGACY USER PUBLIC
|
||||||
/console-api/settings/security SecurityAction GET,POST n API,LEGACY USER PUBLIC
|
/console-api/settings/security SecurityAction POST n API,LEGACY USER PUBLIC
|
||||||
/registrar ConsoleUiAction GET n API,LEGACY NONE PUBLIC
|
/registrar ConsoleUiAction GET n API,LEGACY NONE PUBLIC
|
||||||
/registrar-create ConsoleRegistrarCreatorAction POST,GET n API,LEGACY NONE PUBLIC
|
/registrar-create ConsoleRegistrarCreatorAction POST,GET n API,LEGACY NONE PUBLIC
|
||||||
/registrar-ote-setup ConsoleOteSetupAction POST,GET n API,LEGACY NONE PUBLIC
|
/registrar-ote-setup ConsoleOteSetupAction POST,GET n API,LEGACY NONE PUBLIC
|
||||||
|
|
|
@ -14,19 +14,15 @@
|
||||||
|
|
||||||
package google.registry.util;
|
package google.registry.util;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import dagger.Binds;
|
import dagger.Binds;
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
import dagger.Provides;
|
import dagger.Provides;
|
||||||
import google.registry.util.CidrAddressBlock.CidrAddressBlockAdapter;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.ProviderException;
|
import java.security.ProviderException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import org.joda.time.DateTime;
|
|
||||||
|
|
||||||
/** Dagger module to provide instances of various utils classes. */
|
/** Dagger module to provide instances of various utils classes. */
|
||||||
@Module
|
@Module
|
||||||
|
@ -75,13 +71,4 @@ public abstract class UtilsModule {
|
||||||
return new RandomStringGenerator(StringGenerator.Alphabets.DIGITS_ONLY, secureRandom);
|
return new RandomStringGenerator(StringGenerator.Alphabets.DIGITS_ONLY, secureRandom);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
|
||||||
@Provides
|
|
||||||
public static Gson provideGson() {
|
|
||||||
return new GsonBuilder()
|
|
||||||
.registerTypeAdapter(DateTime.class, new DateTimeTypeAdapter())
|
|
||||||
.registerTypeAdapter(CidrAddressBlock.class, new CidrAddressBlockAdapter())
|
|
||||||
.excludeFieldsWithoutExposeAnnotation()
|
|
||||||
.create();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue