mirror of
https://github.com/google/nomulus.git
synced 2025-05-14 16:37:13 +02:00
Convert RegistrarServlet to RegistrarAction
Convert to an action and remove ResourceServlet, JsonTransportServlet and JsonTransportServlet, all of which exist only to support it. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=137519385
This commit is contained in:
parent
2e4273c4f4
commit
bbd20ec71d
24 changed files with 330 additions and 858 deletions
|
@ -17,6 +17,7 @@ package google.registry.config;
|
||||||
import static google.registry.config.ConfigUtils.makeUrl;
|
import static google.registry.config.ConfigUtils.makeUrl;
|
||||||
|
|
||||||
import com.google.common.base.Optional;
|
import com.google.common.base.Optional;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
import dagger.Provides;
|
import dagger.Provides;
|
||||||
|
@ -325,6 +326,13 @@ public final class ConfigModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Config("registrarChangesNotificationEmailAddresses")
|
||||||
|
public static ImmutableList<String> provideRegistrarChangesNotificationEmailAddresses(
|
||||||
|
RegistryConfig config) {
|
||||||
|
return config.getRegistrarChangesNotificationEmailAddresses();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the publicly accessible domain name for the running Google Apps instance.
|
* Returns the publicly accessible domain name for the running Google Apps instance.
|
||||||
*
|
*
|
||||||
|
|
|
@ -163,7 +163,7 @@ public interface RegistryConfig {
|
||||||
* Returns the email address(es) that notifications of registrar and/or registrar contact updates
|
* Returns the email address(es) that notifications of registrar and/or registrar contact updates
|
||||||
* should be sent to, or the empty list if updates should not be sent.
|
* should be sent to, or the empty list if updates should not be sent.
|
||||||
*
|
*
|
||||||
* @see google.registry.ui.server.registrar.RegistrarServlet
|
* @see google.registry.ui.server.registrar.RegistrarAction
|
||||||
*/
|
*/
|
||||||
public ImmutableList<String> getRegistrarChangesNotificationEmailAddresses();
|
public ImmutableList<String> getRegistrarChangesNotificationEmailAddresses();
|
||||||
|
|
||||||
|
|
|
@ -25,17 +25,6 @@
|
||||||
<url-pattern>/registrar-xhr</url-pattern>
|
<url-pattern>/registrar-xhr</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
<servlet>
|
|
||||||
<display-name>Registrar Self-serve Settings</display-name>
|
|
||||||
<servlet-name>registrar-settings</servlet-name>
|
|
||||||
<servlet-class>google.registry.ui.server.registrar.RegistrarServlet</servlet-class>
|
|
||||||
<load-on-startup>1</load-on-startup>
|
|
||||||
</servlet>
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>registrar-settings</servlet-name>
|
|
||||||
<url-pattern>/registrar-settings</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
|
|
||||||
<!-- Registrar Console. -->
|
<!-- Registrar Console. -->
|
||||||
<servlet-mapping>
|
<servlet-mapping>
|
||||||
<servlet-name>frontend-servlet</servlet-name>
|
<servlet-name>frontend-servlet</servlet-name>
|
||||||
|
@ -54,6 +43,12 @@
|
||||||
<url-pattern>/registrar-payment</url-pattern>
|
<url-pattern>/registrar-payment</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
|
<!-- Registrar Self-serve Settings. -->
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>frontend-servlet</servlet-name>
|
||||||
|
<url-pattern>/registrar-settings</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
<!-- HTTP WHOIS. -->
|
<!-- HTTP WHOIS. -->
|
||||||
<servlet-mapping>
|
<servlet-mapping>
|
||||||
<servlet-name>frontend-servlet</servlet-name>
|
<servlet-name>frontend-servlet</servlet-name>
|
||||||
|
|
|
@ -36,6 +36,7 @@ import google.registry.rdap.RdapNameserverSearchAction;
|
||||||
import google.registry.request.RequestModule;
|
import google.registry.request.RequestModule;
|
||||||
import google.registry.request.RequestScope;
|
import google.registry.request.RequestScope;
|
||||||
import google.registry.ui.server.registrar.ConsoleUiAction;
|
import google.registry.ui.server.registrar.ConsoleUiAction;
|
||||||
|
import google.registry.ui.server.registrar.RegistrarAction;
|
||||||
import google.registry.ui.server.registrar.RegistrarPaymentAction;
|
import google.registry.ui.server.registrar.RegistrarPaymentAction;
|
||||||
import google.registry.ui.server.registrar.RegistrarPaymentSetupAction;
|
import google.registry.ui.server.registrar.RegistrarPaymentSetupAction;
|
||||||
import google.registry.ui.server.registrar.RegistrarUserModule;
|
import google.registry.ui.server.registrar.RegistrarUserModule;
|
||||||
|
@ -65,6 +66,7 @@ interface FrontendRequestComponent {
|
||||||
RdapAutnumAction rdapAutnumAction();
|
RdapAutnumAction rdapAutnumAction();
|
||||||
RegistrarPaymentAction registrarPaymentAction();
|
RegistrarPaymentAction registrarPaymentAction();
|
||||||
RegistrarPaymentSetupAction registrarPaymentSetupAction();
|
RegistrarPaymentSetupAction registrarPaymentSetupAction();
|
||||||
|
RegistrarAction registrarAction();
|
||||||
RdapDomainAction rdapDomainAction();
|
RdapDomainAction rdapDomainAction();
|
||||||
RdapDomainSearchAction rdapDomainSearchAction();
|
RdapDomainSearchAction rdapDomainSearchAction();
|
||||||
RdapEntityAction rdapEntityAction();
|
RdapEntityAction rdapEntityAction();
|
||||||
|
|
|
@ -35,9 +35,13 @@ public final class JsonActionRunner {
|
||||||
Map<String, ?> handleJsonRequest(Map<String, ?> json);
|
Map<String, ?> handleJsonRequest(Map<String, ?> json);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject @JsonPayload Map<String, Object> payload;
|
@JsonPayload Map<String, Object> payload;
|
||||||
@Inject JsonResponse response;
|
JsonResponse response;
|
||||||
@Inject JsonActionRunner() {}
|
|
||||||
|
@Inject public JsonActionRunner(@JsonPayload Map<String, Object> payload, JsonResponse response) {
|
||||||
|
this.payload = payload;
|
||||||
|
this.response = response;
|
||||||
|
}
|
||||||
|
|
||||||
/** Delegates request to {@code action}. */
|
/** Delegates request to {@code action}. */
|
||||||
public void run(JsonAction action) {
|
public void run(JsonAction action) {
|
||||||
|
|
|
@ -28,16 +28,3 @@ java_library(
|
||||||
"//java/google/registry/util",
|
"//java/google/registry/util",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
java_library(
|
|
||||||
name = "servlets",
|
|
||||||
srcs = glob(["*Servlet.java"]),
|
|
||||||
deps = [
|
|
||||||
":security",
|
|
||||||
"//java/com/google/common/base",
|
|
||||||
"//third_party/java/appengine:appengine-api",
|
|
||||||
"//third_party/java/joda_time",
|
|
||||||
"//third_party/java/servlet/servlet_api",
|
|
||||||
"//java/google/registry/request",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
// Copyright 2016 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.security;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
|
|
||||||
import static javax.servlet.http.HttpServletResponse.SC_OK;
|
|
||||||
|
|
||||||
import google.registry.request.HttpException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Map;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Secure servlet that speaks JSON for both input and output.
|
|
||||||
*
|
|
||||||
* <p>This servlet accepts only JSON inputs (using the payload) and returns only JSON
|
|
||||||
* responses, using and various security best practices such as a parser breaker,
|
|
||||||
* {@code Content-Disposition: attachment}, etc.
|
|
||||||
*
|
|
||||||
* @see JsonHttp
|
|
||||||
*/
|
|
||||||
public abstract class JsonTransportServlet extends XsrfProtectedServlet {
|
|
||||||
|
|
||||||
protected JsonTransportServlet(String xsrfScope, boolean requireAdmin) {
|
|
||||||
super(xsrfScope, requireAdmin);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify that this is a well-formed request and then execute it. A well-formed request will have
|
|
||||||
* either a JSON string in the "json" param that evaluates to a map, or nothing in "json".
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected final void doPost(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
|
|
||||||
Map<String, ?> input = JsonHttp.read(req);
|
|
||||||
if (input == null) {
|
|
||||||
rsp.sendError(SC_BAD_REQUEST, "Malformed JSON");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Map<String, ?> output;
|
|
||||||
try {
|
|
||||||
output = doJsonPost(req, input);
|
|
||||||
} catch (HttpException e) {
|
|
||||||
e.send(rsp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
checkNotNull(output, "doJsonPost() returned null");
|
|
||||||
rsp.setStatus(SC_OK);
|
|
||||||
JsonHttp.write(rsp, output);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler for HTTP POST requests.
|
|
||||||
*
|
|
||||||
* @param req Servlet request object.
|
|
||||||
* @param input JSON request object or empty if none was provided.
|
|
||||||
* @return an arbitrary JSON object. Must not be {@code null}.
|
|
||||||
* @throws HttpException in order to send a non-200 status code / message to the client.
|
|
||||||
*/
|
|
||||||
public abstract Map<String, Object> doJsonPost(HttpServletRequest req, Map<String, ?> input);
|
|
||||||
}
|
|
|
@ -1,83 +0,0 @@
|
||||||
// Copyright 2016 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.security;
|
|
||||||
|
|
||||||
import static com.google.appengine.api.users.UserServiceFactory.getUserService;
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
import static com.google.common.base.Strings.nullToEmpty;
|
|
||||||
import static google.registry.security.XsrfTokenManager.X_CSRF_TOKEN;
|
|
||||||
import static google.registry.security.XsrfTokenManager.validateToken;
|
|
||||||
import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
|
|
||||||
|
|
||||||
import com.google.appengine.api.users.UserService;
|
|
||||||
import java.io.IOException;
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.http.HttpServlet;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import org.joda.time.Duration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Servlet with Cross-Site Request Forgery (XSRF) protection.
|
|
||||||
*
|
|
||||||
* <p>This servlet enforces XSRF protection on all requests by checking the value provided in the
|
|
||||||
* "X-CSRF-Token" header. It can also optionally enforce that only admin users can call it.
|
|
||||||
*
|
|
||||||
* <p>All servlets that handle client requests should use XSRF protection.
|
|
||||||
*/
|
|
||||||
public abstract class XsrfProtectedServlet extends HttpServlet {
|
|
||||||
|
|
||||||
private static final Duration XSRF_VALIDITY = Duration.standardDays(1);
|
|
||||||
|
|
||||||
/** Used to validate XSRF tokens. */
|
|
||||||
private String xsrfScope;
|
|
||||||
|
|
||||||
/** Whether to do a security check for admin status. */
|
|
||||||
private boolean requireAdmin;
|
|
||||||
|
|
||||||
/** Gets the XSRF scope for this servlet. */
|
|
||||||
public String getScope() {
|
|
||||||
return xsrfScope;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected XsrfProtectedServlet(String xsrfScope, boolean requireAdmin) {
|
|
||||||
this.xsrfScope = checkNotNull(xsrfScope);
|
|
||||||
this.requireAdmin = requireAdmin;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void service(HttpServletRequest req, HttpServletResponse rsp)
|
|
||||||
throws IOException, ServletException {
|
|
||||||
if (!validateToken(nullToEmpty(req.getHeader(X_CSRF_TOKEN)), xsrfScope, XSRF_VALIDITY)) {
|
|
||||||
rsp.sendError(SC_FORBIDDEN, "Invalid " + X_CSRF_TOKEN);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!validateAdmin()) {
|
|
||||||
rsp.sendError(SC_FORBIDDEN, "Administrator access only");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
doPost(req, rsp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If this is an admin-only servlet, require admin permissions or being in development mode. Such
|
|
||||||
* servlets should primarily be defended by being marked internal-only in web.xml, but it's worth
|
|
||||||
* adding a defense-in-depth.
|
|
||||||
*/
|
|
||||||
private boolean validateAdmin() {
|
|
||||||
UserService userService = getUserService();
|
|
||||||
return requireAdmin ? (userService.isUserLoggedIn() && userService.isUserAdmin()) : true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -26,7 +26,6 @@ java_library(
|
||||||
"//java/google/registry/model",
|
"//java/google/registry/model",
|
||||||
"//java/google/registry/request",
|
"//java/google/registry/request",
|
||||||
"//java/google/registry/security",
|
"//java/google/registry/security",
|
||||||
"//java/google/registry/security:servlets",
|
|
||||||
"//java/google/registry/ui/forms",
|
"//java/google/registry/ui/forms",
|
||||||
"//java/google/registry/ui/server",
|
"//java/google/registry/ui/server",
|
||||||
"//java/google/registry/ui/soy:soy_java_wrappers",
|
"//java/google/registry/ui/soy:soy_java_wrappers",
|
||||||
|
|
|
@ -18,23 +18,29 @@ import static com.google.common.collect.Iterables.any;
|
||||||
import static com.google.common.collect.Iterables.concat;
|
import static com.google.common.collect.Iterables.concat;
|
||||||
import static com.google.common.collect.Sets.difference;
|
import static com.google.common.collect.Sets.difference;
|
||||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||||
|
import static google.registry.security.JsonResponseHelper.Status.ERROR;
|
||||||
import static google.registry.security.JsonResponseHelper.Status.SUCCESS;
|
import static google.registry.security.JsonResponseHelper.Status.SUCCESS;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Optional;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.FluentIterable;
|
import com.google.common.collect.FluentIterable;
|
||||||
import com.google.common.collect.HashMultimap;
|
import com.google.common.collect.HashMultimap;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import com.googlecode.objectify.Work;
|
import com.googlecode.objectify.Work;
|
||||||
import google.registry.config.RegistryConfig;
|
import google.registry.config.ConfigModule.Config;
|
||||||
import google.registry.config.RegistryEnvironment;
|
|
||||||
import google.registry.export.sheet.SyncRegistrarsSheetAction;
|
import google.registry.export.sheet.SyncRegistrarsSheetAction;
|
||||||
import google.registry.model.registrar.Registrar;
|
import google.registry.model.registrar.Registrar;
|
||||||
import google.registry.model.registrar.RegistrarContact;
|
import google.registry.model.registrar.RegistrarContact;
|
||||||
|
import google.registry.request.Action;
|
||||||
|
import google.registry.request.HttpException.BadRequestException;
|
||||||
|
import google.registry.request.JsonActionRunner;
|
||||||
import google.registry.security.JsonResponseHelper;
|
import google.registry.security.JsonResponseHelper;
|
||||||
import google.registry.ui.forms.FormException;
|
import google.registry.ui.forms.FormException;
|
||||||
|
import google.registry.ui.forms.FormFieldException;
|
||||||
import google.registry.ui.server.RegistrarFormFields;
|
import google.registry.ui.server.RegistrarFormFields;
|
||||||
import google.registry.util.CidrAddressBlock;
|
import google.registry.util.CidrAddressBlock;
|
||||||
import google.registry.util.CollectionUtils;
|
import google.registry.util.CollectionUtils;
|
||||||
|
@ -44,15 +50,33 @@ import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import javax.inject.Inject;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Admin servlet that allows creating or updating a registrar. Deletes are not allowed so as to
|
* Admin servlet that allows creating or updating a registrar. Deletes are not allowed so as to
|
||||||
* preserve history.
|
* preserve history.
|
||||||
*/
|
*/
|
||||||
public class RegistrarServlet extends ResourceServlet {
|
@Action(
|
||||||
|
path = RegistrarAction.PATH,
|
||||||
|
requireLogin = true,
|
||||||
|
xsrfProtection = true,
|
||||||
|
xsrfScope = "console",
|
||||||
|
method = Action.Method.POST)
|
||||||
|
public class RegistrarAction implements Runnable, JsonActionRunner.JsonAction {
|
||||||
|
|
||||||
private static final RegistryConfig CONFIG = RegistryEnvironment.get().config();
|
public static final String PATH = "/registrar-settings";
|
||||||
|
|
||||||
|
private static final String OP_PARAM = "op";
|
||||||
|
private static final String ARGS_PARAM = "args";
|
||||||
|
|
||||||
|
@Inject HttpServletRequest request;
|
||||||
|
@Inject SessionUtils sessionUtils;
|
||||||
|
@Inject JsonActionRunner jsonActionRunner;
|
||||||
|
@Inject Registrar initialRegistrar;
|
||||||
|
@Inject @Config("registrarChangesNotificationEmailAddresses") ImmutableList<String>
|
||||||
|
registrarChangesNotificationEmailAddresses;
|
||||||
|
@Inject RegistrarAction() {}
|
||||||
|
|
||||||
private static final Predicate<RegistrarContact> HAS_PHONE = new Predicate<RegistrarContact>() {
|
private static final Predicate<RegistrarContact> HAS_PHONE = new Predicate<RegistrarContact>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -71,25 +95,20 @@ public class RegistrarServlet extends ResourceServlet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public Map<String, Object> read(Map<String, ?> args, Registrar registrar) {
|
||||||
public Map<String, Object> read(HttpServletRequest req, Map<String, ?> args) {
|
|
||||||
String clientId = sessionUtils.getRegistrarClientId(req);
|
|
||||||
Registrar registrar = getCheckedRegistrar(clientId);
|
|
||||||
return JsonResponseHelper.create(SUCCESS, "Success", registrar.toJsonMap());
|
return JsonResponseHelper.create(SUCCESS, "Success", registrar.toJsonMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
Map<String, Object> update(final Map<String, ?> args, final Registrar registrar) {
|
||||||
Map<String, Object> update(HttpServletRequest req, final Map<String, ?> args) {
|
final String clientId = sessionUtils.getRegistrarClientId(request);
|
||||||
final String clientId = sessionUtils.getRegistrarClientId(req);
|
|
||||||
return ofy().transact(new Work<Map<String, Object>>() {
|
return ofy().transact(new Work<Map<String, Object>>() {
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> run() {
|
public Map<String, Object> run() {
|
||||||
Registrar existingRegistrar = getCheckedRegistrar(clientId);
|
ImmutableSet<RegistrarContact> oldContacts = registrar.getContacts();
|
||||||
ImmutableSet<RegistrarContact> oldContacts = existingRegistrar.getContacts();
|
|
||||||
Map<String, Object> existingRegistrarMap =
|
Map<String, Object> existingRegistrarMap =
|
||||||
expandRegistrarWithContacts(existingRegistrar, oldContacts);
|
expandRegistrarWithContacts(oldContacts, registrar);
|
||||||
Registrar.Builder builder = existingRegistrar.asBuilder();
|
Registrar.Builder builder = registrar.asBuilder();
|
||||||
ImmutableSet<RegistrarContact> updatedContacts = update(existingRegistrar, builder, args);
|
ImmutableSet<RegistrarContact> updatedContacts = update(registrar, builder, args);
|
||||||
if (!updatedContacts.isEmpty()) {
|
if (!updatedContacts.isEmpty()) {
|
||||||
builder.setContactsRequireSyncing(true);
|
builder.setContactsRequireSyncing(true);
|
||||||
}
|
}
|
||||||
|
@ -102,7 +121,7 @@ public class RegistrarServlet extends ResourceServlet {
|
||||||
// Update the registrar map with updated contacts to bypass Objectify caching issues that
|
// Update the registrar map with updated contacts to bypass Objectify caching issues that
|
||||||
// come into play with calling getContacts().
|
// come into play with calling getContacts().
|
||||||
Map<String, Object> updatedRegistrarMap =
|
Map<String, Object> updatedRegistrarMap =
|
||||||
expandRegistrarWithContacts(updatedRegistrar, updatedContacts);
|
expandRegistrarWithContacts(updatedContacts, updatedRegistrar);
|
||||||
sendExternalUpdatesIfNecessary(
|
sendExternalUpdatesIfNecessary(
|
||||||
updatedRegistrar.getRegistrarName(),
|
updatedRegistrar.getRegistrarName(),
|
||||||
existingRegistrarMap,
|
existingRegistrarMap,
|
||||||
|
@ -114,8 +133,8 @@ public class RegistrarServlet extends ResourceServlet {
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Object> expandRegistrarWithContacts(
|
private Map<String, Object> expandRegistrarWithContacts(Iterable<RegistrarContact> contacts,
|
||||||
Registrar registrar, Iterable<RegistrarContact> contacts) {
|
Registrar registrar) {
|
||||||
ImmutableSet<Map<String, Object>> expandedContacts = FluentIterable.from(contacts)
|
ImmutableSet<Map<String, Object>> expandedContacts = FluentIterable.from(contacts)
|
||||||
.transform(new Function<RegistrarContact, Map<String, Object>>() {
|
.transform(new Function<RegistrarContact, Map<String, Object>>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -146,21 +165,15 @@ public class RegistrarServlet extends ResourceServlet {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SyncRegistrarsSheetAction.enqueueBackendTask();
|
SyncRegistrarsSheetAction.enqueueBackendTask();
|
||||||
ImmutableList<String> toEmailAddress = CONFIG.getRegistrarChangesNotificationEmailAddresses();
|
if (!registrarChangesNotificationEmailAddresses.isEmpty()) {
|
||||||
if (!toEmailAddress.isEmpty()) {
|
|
||||||
SendEmailUtils.sendEmail(
|
SendEmailUtils.sendEmail(
|
||||||
toEmailAddress,
|
registrarChangesNotificationEmailAddresses,
|
||||||
String.format("Registrar %s updated", registrarName),
|
String.format("Registrar %s updated", registrarName),
|
||||||
"The following changes were made to the registrar:\n"
|
"The following changes were made to the registrar:\n"
|
||||||
+ DiffUtils.prettyPrintDiffedMap(diffs, null));
|
+ DiffUtils.prettyPrintDiffedMap(diffs, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Registrar getCheckedRegistrar(String clientId) {
|
|
||||||
return checkExists(Registrar.loadByClientId(clientId),
|
|
||||||
"No registrar exists with the given client id: " + clientId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enforces business logic checks on registrar contacts.
|
* Enforces business logic checks on registrar contacts.
|
||||||
*
|
*
|
||||||
|
@ -255,4 +268,42 @@ public class RegistrarServlet extends ResourceServlet {
|
||||||
|
|
||||||
return contacts.build();
|
return contacts.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> handleJsonRequest(Map<String, ?> input) {
|
||||||
|
if (input == null) {
|
||||||
|
throw new BadRequestException("Malformed JSON");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sessionUtils.checkRegistrarConsoleLogin(request)) {
|
||||||
|
return JsonResponseHelper.create(ERROR, "Not authorized to access Registrar Console");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the operation. Though originally derived from a CRUD
|
||||||
|
// handlder, registrar-settings really only supports read and update.
|
||||||
|
String op = Optional.fromNullable((String) input.get(OP_PARAM)).or("read");
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Map<String, ?> args = (Map<String, Object>)
|
||||||
|
Optional.<Object>fromNullable(input.get(ARGS_PARAM)).or(ImmutableMap.of());
|
||||||
|
try {
|
||||||
|
switch (op) {
|
||||||
|
case "update":
|
||||||
|
return update(args, initialRegistrar);
|
||||||
|
case "read":
|
||||||
|
return read(args, initialRegistrar);
|
||||||
|
default:
|
||||||
|
return JsonResponseHelper.create(ERROR, "Unknown or unsupported operation: " + op);
|
||||||
|
}
|
||||||
|
} catch (FormFieldException e) {
|
||||||
|
return JsonResponseHelper.createFormFieldError(e.getMessage(), e.getFieldName());
|
||||||
|
} catch (FormException ee) {
|
||||||
|
return JsonResponseHelper.create(ERROR, ee.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
jsonActionRunner.run(this);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,105 +0,0 @@
|
||||||
// Copyright 2016 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.ui.server.registrar;
|
|
||||||
|
|
||||||
import static com.google.appengine.api.users.UserServiceFactory.getUserService;
|
|
||||||
import static google.registry.flows.EppConsoleAction.XSRF_SCOPE;
|
|
||||||
import static google.registry.security.JsonResponseHelper.Status.ERROR;
|
|
||||||
|
|
||||||
import com.google.common.base.Optional;
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
import google.registry.request.HttpException.NotFoundException;
|
|
||||||
import google.registry.security.JsonResponseHelper;
|
|
||||||
import google.registry.security.JsonTransportServlet;
|
|
||||||
import google.registry.ui.forms.FormException;
|
|
||||||
import google.registry.ui.forms.FormFieldException;
|
|
||||||
import google.registry.util.NonFinalForTesting;
|
|
||||||
import java.util.Map;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
/** A servlet for callbacks that manipulate resources. */
|
|
||||||
public abstract class ResourceServlet extends JsonTransportServlet {
|
|
||||||
|
|
||||||
private static final String OP_PARAM = "op";
|
|
||||||
private static final String ARGS_PARAM = "args";
|
|
||||||
|
|
||||||
@NonFinalForTesting
|
|
||||||
protected static SessionUtils sessionUtils = new SessionUtils(getUserService());
|
|
||||||
|
|
||||||
public ResourceServlet() {
|
|
||||||
super(XSRF_SCOPE, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, Object> doJsonPost(HttpServletRequest req, Map<String, ?> params) {
|
|
||||||
if (!sessionUtils.isLoggedIn()) {
|
|
||||||
return JsonResponseHelper.create(ERROR, "Not logged in");
|
|
||||||
}
|
|
||||||
if (!sessionUtils.checkRegistrarConsoleLogin(req)) {
|
|
||||||
return JsonResponseHelper.create(ERROR, "Not authorized to access Registrar Console");
|
|
||||||
}
|
|
||||||
String op = Optional.fromNullable((String) params.get(OP_PARAM)).or("read");
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Map<String, ?> args = (Map<String, Object>)
|
|
||||||
Optional.<Object>fromNullable(params.get(ARGS_PARAM)).or(ImmutableMap.of());
|
|
||||||
try {
|
|
||||||
switch (op) {
|
|
||||||
case "create":
|
|
||||||
return create(req, args);
|
|
||||||
case "update":
|
|
||||||
return update(req, args);
|
|
||||||
case "delete":
|
|
||||||
return delete(req, args);
|
|
||||||
case "read":
|
|
||||||
return read(req, args);
|
|
||||||
default:
|
|
||||||
return JsonResponseHelper.create(ERROR, "Unknown operation: " + op);
|
|
||||||
}
|
|
||||||
} catch (FormFieldException e) {
|
|
||||||
return JsonResponseHelper.createFormFieldError(e.getMessage(), e.getFieldName());
|
|
||||||
} catch (FormException ee) {
|
|
||||||
return JsonResponseHelper.create(ERROR, ee.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
Map<String, Object> create(HttpServletRequest req, Map<String, ?> args) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
Map<String, Object> read(HttpServletRequest req, Map<String, ?> args) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
Map<String, Object> update(HttpServletRequest req, Map<String, ?> args) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
Map<String, Object> delete(HttpServletRequest req, Map<String, ?> args) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Like checkNotNull, but throws NotFoundException if given arg is null. */
|
|
||||||
protected static <T> T checkExists(@Nullable T obj, String msg) {
|
|
||||||
if (obj == null) {
|
|
||||||
throw new NotFoundException(msg);
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -51,6 +51,12 @@ public final class RequestModuleTest {
|
||||||
provideJsonPayload(MediaType.JSON_UTF_8, "{\"k\":");
|
provideJsonPayload(MediaType.JSON_UTF_8, "{\"k\":");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testProvideJsonPayload_emptyInput_throws500() throws Exception {
|
||||||
|
thrown.expect(BadRequestException.class, "Malformed JSON");
|
||||||
|
provideJsonPayload(MediaType.JSON_UTF_8, "");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testProvideJsonPayload_nonJsonContentType_throws415() throws Exception {
|
public void testProvideJsonPayload_nonJsonContentType_throws415() throws Exception {
|
||||||
thrown.expect(UnsupportedMediaTypeException.class);
|
thrown.expect(UnsupportedMediaTypeException.class);
|
||||||
|
|
|
@ -32,28 +32,10 @@ java_library(
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
java_library(
|
|
||||||
name = "servlets",
|
|
||||||
srcs = glob(["*ServletTest.java"]),
|
|
||||||
deps = [
|
|
||||||
"//java/com/google/common/collect",
|
|
||||||
"//java/com/google/common/net",
|
|
||||||
"//third_party/java/junit",
|
|
||||||
"//third_party/java/mockito",
|
|
||||||
"//third_party/java/servlet/servlet_api",
|
|
||||||
"//third_party/java/truth",
|
|
||||||
"//java/google/registry/request",
|
|
||||||
"//java/google/registry/security",
|
|
||||||
"//java/google/registry/security:servlets",
|
|
||||||
"//javatests/google/registry/testing",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
GenTestRules(
|
GenTestRules(
|
||||||
name = "GeneratedTestRules",
|
name = "GeneratedTestRules",
|
||||||
test_files = glob(["*Test.java"]),
|
test_files = glob(["*Test.java"]),
|
||||||
deps = [
|
deps = [
|
||||||
":security",
|
":security",
|
||||||
":servlets",
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -43,8 +43,8 @@ public final class JsonHttpTestUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns JSON data parsed out of a JsonTransportServlet response stored in the given writer.
|
* Returns JSON data parsed out of the contents of the given writer. If the data will be fetched
|
||||||
* If the data will be fetched multiple times, consider {@link #createJsonResponseSupplier}.
|
* multiple times, consider {@link #createJsonResponseSupplier}.
|
||||||
*
|
*
|
||||||
* <p>Example Mockito usage:<pre> {@code
|
* <p>Example Mockito usage:<pre> {@code
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,156 +0,0 @@
|
||||||
// Copyright 2016 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.security;
|
|
||||||
|
|
||||||
import static com.google.common.net.HttpHeaders.CONTENT_DISPOSITION;
|
|
||||||
import static com.google.common.net.HttpHeaders.X_CONTENT_TYPE_OPTIONS;
|
|
||||||
import static com.google.common.net.MediaType.JSON_UTF_8;
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
|
||||||
import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
|
|
||||||
import static javax.servlet.http.HttpServletResponse.SC_OK;
|
|
||||||
import static org.mockito.Matchers.anyString;
|
|
||||||
import static org.mockito.Matchers.eq;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
import google.registry.request.HttpException;
|
|
||||||
import google.registry.testing.AppEngineRule;
|
|
||||||
import google.registry.testing.ExceptionRule;
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.io.StringReader;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.util.Map;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
|
||||||
|
|
||||||
/** Unit tests for {@link JsonTransportServlet}. */
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
|
||||||
public class JsonTransportServletTest {
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public final AppEngineRule appEngine = AppEngineRule.builder()
|
|
||||||
.withDatastore()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public final ExceptionRule thrown = new ExceptionRule();
|
|
||||||
|
|
||||||
private StringWriter writer = new StringWriter();
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
HttpServletRequest req;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
HttpServletResponse rsp;
|
|
||||||
|
|
||||||
static class TestServlet extends JsonTransportServlet {
|
|
||||||
private Map<String, Object> responseMap;
|
|
||||||
|
|
||||||
TestServlet(Map<String, Object> responseMap) {
|
|
||||||
super("foo", false);
|
|
||||||
this.responseMap = responseMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, Object> doJsonPost(HttpServletRequest req, Map<String, ?> input) {
|
|
||||||
return responseMap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifySuccess(String json) {
|
|
||||||
verify(rsp).setStatus(SC_OK);
|
|
||||||
verify(rsp).setHeader(CONTENT_DISPOSITION, "attachment");
|
|
||||||
verify(rsp).setHeader(X_CONTENT_TYPE_OPTIONS, "nosniff");
|
|
||||||
verify(rsp).setContentType(JSON_UTF_8.toString());
|
|
||||||
assertThat(writer.toString()).isEqualTo(")]}'\n" + json);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doSuccessfulTest(
|
|
||||||
String requestJson, Map<String, Object> responseMap) throws Exception {
|
|
||||||
when(req.getMethod()).thenReturn("POST");
|
|
||||||
when(req.getContentType()).thenReturn(JSON_UTF_8.toString());
|
|
||||||
when(req.getReader()).thenReturn(new BufferedReader(new StringReader(requestJson)));
|
|
||||||
when(rsp.getWriter()).thenReturn(new PrintWriter(writer));
|
|
||||||
new TestServlet(responseMap).doPost(req, rsp);
|
|
||||||
verifySuccess("{\"a\":1}");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifyFailure(int error) throws Exception {
|
|
||||||
verify(rsp).sendError(eq(error), anyString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSuccess() throws Exception {
|
|
||||||
doSuccessfulTest("{\"key\":\"value\"}", ImmutableMap.<String, Object>of("a", 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDoJsonPost_returnsNull_notAllowed() throws Exception {
|
|
||||||
when(req.getMethod()).thenReturn("POST");
|
|
||||||
when(req.getContentType()).thenReturn(JSON_UTF_8.toString());
|
|
||||||
when(req.getReader()).thenReturn(new BufferedReader(new StringReader("{\"key\":\"value\"}")));
|
|
||||||
when(rsp.getWriter()).thenReturn(new PrintWriter(writer));
|
|
||||||
thrown.expect(NullPointerException.class);
|
|
||||||
new TestServlet(null).doPost(req, rsp);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doInvalidRequestTest(String requestJson) throws Exception {
|
|
||||||
when(req.getMethod()).thenReturn("POST");
|
|
||||||
when(req.getContentType()).thenReturn(JSON_UTF_8.toString());
|
|
||||||
when(req.getReader()).thenReturn(new BufferedReader(new StringReader(requestJson)));
|
|
||||||
new TestServlet(null).doPost(req, rsp);
|
|
||||||
verifyFailure(SC_BAD_REQUEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSuccess_emptyJsonNotAllowed() throws Exception {
|
|
||||||
doInvalidRequestTest("");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFailure_badJson() throws Exception {
|
|
||||||
doInvalidRequestTest("{}{}");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFailure_nonObjectJson_null() throws Exception {
|
|
||||||
doInvalidRequestTest("null");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFailure_nonObjectJson_array() throws Exception {
|
|
||||||
doInvalidRequestTest("[]");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testErrorMessagesAreEscaped() throws Exception {
|
|
||||||
when(req.getMethod()).thenReturn("POST");
|
|
||||||
when(req.getReader()).thenReturn(new BufferedReader(new StringReader("{}")));
|
|
||||||
when(req.getContentType()).thenReturn(JSON_UTF_8.toString());
|
|
||||||
new TestServlet(null) {
|
|
||||||
@Override
|
|
||||||
public Map<String, Object> doJsonPost(HttpServletRequest req, Map<String, ?> input) {
|
|
||||||
throw new HttpException(123, "<script>", null){};
|
|
||||||
}}.doPost(req, rsp);
|
|
||||||
verify(rsp).sendError(123, "<script>");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,105 +0,0 @@
|
||||||
// Copyright 2016 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.security;
|
|
||||||
|
|
||||||
import static google.registry.security.XsrfTokenManager.X_CSRF_TOKEN;
|
|
||||||
import static google.registry.security.XsrfTokenManager.generateToken;
|
|
||||||
import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
|
|
||||||
import static javax.servlet.http.HttpServletResponse.SC_OK;
|
|
||||||
import static org.mockito.Matchers.anyString;
|
|
||||||
import static org.mockito.Matchers.eq;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import google.registry.testing.AppEngineRule;
|
|
||||||
import google.registry.testing.UserInfo;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
|
||||||
|
|
||||||
/** Unit tests for {@link XsrfProtectedServlet}. */
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
|
||||||
public class XsrfProtectedServletTest {
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public final AppEngineRule appEngine = AppEngineRule.builder()
|
|
||||||
.withDatastore()
|
|
||||||
.withUserService(UserInfo.create("test@example.com", "test@example.com"))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
HttpServletRequest req;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
HttpServletResponse rsp;
|
|
||||||
|
|
||||||
XsrfProtectedServlet servlet = new XsrfProtectedServlet("foo", false) {
|
|
||||||
@Override
|
|
||||||
protected void doPost(HttpServletRequest req, HttpServletResponse rsp) {
|
|
||||||
rsp.setStatus(SC_OK);
|
|
||||||
}};
|
|
||||||
|
|
||||||
String validXsrfToken;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void init() {
|
|
||||||
this.validXsrfToken = generateToken("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setup(String xsrf, String method) throws Exception {
|
|
||||||
when(req.getHeader(X_CSRF_TOKEN)).thenReturn(xsrf);
|
|
||||||
when(req.getMethod()).thenReturn(method);
|
|
||||||
when(req.getServletPath()).thenReturn("");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSuccess() throws Exception {
|
|
||||||
setup(validXsrfToken, "post");
|
|
||||||
servlet.service(req, rsp);
|
|
||||||
verify(rsp).setStatus(SC_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doInvalidRequestTest(String xsrf) throws Exception {
|
|
||||||
setup(xsrf, "post");
|
|
||||||
servlet.service(req, rsp);
|
|
||||||
verify(rsp).sendError(eq(SC_FORBIDDEN), anyString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFailure_badXsrfToken() throws Exception {
|
|
||||||
doInvalidRequestTest("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFailure_missingXsrfToken() throws Exception {
|
|
||||||
doInvalidRequestTest(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFailure_notAdmin() throws Exception {
|
|
||||||
setup(validXsrfToken, "post");
|
|
||||||
new XsrfProtectedServlet("foo", true) {
|
|
||||||
@Override
|
|
||||||
protected void doPost(HttpServletRequest req, HttpServletResponse rsp) {
|
|
||||||
rsp.setStatus(SC_OK);
|
|
||||||
}}.service(req, rsp);
|
|
||||||
verify(rsp).sendError(eq(SC_FORBIDDEN), anyString());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -79,7 +79,7 @@ public final class RegistryTestServer {
|
||||||
// Registrar Console
|
// Registrar Console
|
||||||
route("/registrar", google.registry.module.frontend.FrontendServlet.class),
|
route("/registrar", google.registry.module.frontend.FrontendServlet.class),
|
||||||
route("/registrar-settings",
|
route("/registrar-settings",
|
||||||
google.registry.ui.server.registrar.RegistrarServlet.class),
|
google.registry.module.frontend.FrontendServlet.class),
|
||||||
route("/registrar-payment",
|
route("/registrar-payment",
|
||||||
google.registry.module.frontend.FrontendServlet.class),
|
google.registry.module.frontend.FrontendServlet.class),
|
||||||
route("/registrar-payment-setup",
|
route("/registrar-payment-setup",
|
||||||
|
|
|
@ -32,6 +32,7 @@ java_library(
|
||||||
"//java/google/registry/config",
|
"//java/google/registry/config",
|
||||||
"//java/google/registry/export/sheet",
|
"//java/google/registry/export/sheet",
|
||||||
"//java/google/registry/model",
|
"//java/google/registry/model",
|
||||||
|
"//java/google/registry/request",
|
||||||
"//java/google/registry/security",
|
"//java/google/registry/security",
|
||||||
"//java/google/registry/ui/server/registrar",
|
"//java/google/registry/ui/server/registrar",
|
||||||
"//java/google/registry/ui/soy/registrar:soy_java_wrappers",
|
"//java/google/registry/ui/soy/registrar:soy_java_wrappers",
|
||||||
|
|
|
@ -15,10 +15,8 @@
|
||||||
package google.registry.ui.server.registrar;
|
package google.registry.ui.server.registrar;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static google.registry.security.JsonHttpTestUtils.createJsonPayload;
|
|
||||||
import static google.registry.testing.DatastoreHelper.persistResource;
|
import static google.registry.testing.DatastoreHelper.persistResource;
|
||||||
import static google.registry.testing.DatastoreHelper.persistSimpleResource;
|
import static google.registry.testing.DatastoreHelper.persistSimpleResource;
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
@ -34,33 +32,31 @@ import org.junit.runner.RunWith;
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for contact_settings.js use of {@link RegistrarServlet}.
|
* Unit tests for contact_settings.js use of {@link RegistrarAction}.
|
||||||
*
|
*
|
||||||
* <p>The default read and session validation tests are handled by the
|
* <p>The default read and session validation tests are handled by the
|
||||||
* superclass.
|
* superclass.
|
||||||
*/
|
*/
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class ContactSettingsTest extends RegistrarServletTestCase {
|
public class ContactSettingsTest extends RegistrarActionTestCase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPost_readContacts_success() throws Exception {
|
public void testPost_readContacts_success() throws Exception {
|
||||||
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
|
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
|
||||||
"op", "read",
|
"op", "read",
|
||||||
"args", ImmutableMap.of())));
|
"args", ImmutableMap.of()));
|
||||||
servlet.service(req, rsp);
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
List<Map<String, ?>> results = (List<Map<String, ?>>) json.get().get("results");
|
List<Map<String, ?>> results = (List<Map<String, ?>>) response.get("results");
|
||||||
assertThat(results.get(0).get("contacts"))
|
assertThat(results.get(0).get("contacts"))
|
||||||
.isEqualTo(Registrar.loadByClientId(CLIENT_ID).toJsonMap().get("contacts"));
|
.isEqualTo(Registrar.loadByClientId(CLIENT_ID).toJsonMap().get("contacts"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPost_loadSaveRegistrar_success() throws Exception {
|
public void testPost_loadSaveRegistrar_success() throws Exception {
|
||||||
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
|
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
|
||||||
"op", "update",
|
"op", "update",
|
||||||
"args", Registrar.loadByClientId(CLIENT_ID).toJsonMap())));
|
"args", Registrar.loadByClientId(CLIENT_ID).toJsonMap()));
|
||||||
servlet.service(req, rsp);
|
assertThat(response).containsEntry("status", "SUCCESS");
|
||||||
assertThat(json.get()).containsEntry("status", "SUCCESS");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -77,11 +73,10 @@ public class ContactSettingsTest extends RegistrarServletTestCase {
|
||||||
Registrar registrar = Registrar.loadByClientId(CLIENT_ID);
|
Registrar registrar = Registrar.loadByClientId(CLIENT_ID);
|
||||||
Map<String, Object> regMap = registrar.toJsonMap();
|
Map<String, Object> regMap = registrar.toJsonMap();
|
||||||
regMap.put("contacts", ImmutableList.of(adminContact1));
|
regMap.put("contacts", ImmutableList.of(adminContact1));
|
||||||
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
|
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
|
||||||
"op", "update",
|
"op", "update",
|
||||||
"args", regMap)));
|
"args", regMap));
|
||||||
servlet.service(req, rsp);
|
assertThat(response).containsEntry("status", "SUCCESS");
|
||||||
assertThat(json.get()).containsEntry("status", "SUCCESS");
|
|
||||||
|
|
||||||
RegistrarContact newContact = new RegistrarContact.Builder()
|
RegistrarContact newContact = new RegistrarContact.Builder()
|
||||||
.setParent(registrar)
|
.setParent(registrar)
|
||||||
|
@ -102,12 +97,11 @@ public class ContactSettingsTest extends RegistrarServletTestCase {
|
||||||
.asBuilder()
|
.asBuilder()
|
||||||
.setTypes(ImmutableList.<RegistrarContact.Type>of())
|
.setTypes(ImmutableList.<RegistrarContact.Type>of())
|
||||||
.build().toJsonMap()));
|
.build().toJsonMap()));
|
||||||
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
|
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
|
||||||
"op", "update",
|
"op", "update",
|
||||||
"args", reqJson)));
|
"args", reqJson));
|
||||||
servlet.service(req, rsp);
|
assertThat(response).containsEntry("status", "ERROR");
|
||||||
assertThat(json.get()).containsEntry("status", "ERROR");
|
assertThat(response).containsEntry("message", "Must have at least one "
|
||||||
assertThat(json.get()).containsEntry("message", "Must have at least one "
|
|
||||||
+ RegistrarContact.Type.ADMIN.getDisplayName() + " contact");
|
+ RegistrarContact.Type.ADMIN.getDisplayName() + " contact");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,12 +121,11 @@ public class ContactSettingsTest extends RegistrarServletTestCase {
|
||||||
rc = rc.asBuilder().setPhoneNumber(null).build();
|
rc = rc.asBuilder().setPhoneNumber(null).build();
|
||||||
Map<String, Object> reqJson = registrar.toJsonMap();
|
Map<String, Object> reqJson = registrar.toJsonMap();
|
||||||
reqJson.put("contacts", ImmutableList.of(rc.toJsonMap()));
|
reqJson.put("contacts", ImmutableList.of(rc.toJsonMap()));
|
||||||
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
|
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
|
||||||
"op", "update",
|
"op", "update",
|
||||||
"args", reqJson)));
|
"args", reqJson));
|
||||||
servlet.service(req, rsp);
|
assertThat(response).containsEntry("status", "ERROR");
|
||||||
assertThat(json.get()).containsEntry("status", "ERROR");
|
assertThat(response).containsEntry("message", "At least one "
|
||||||
assertThat(json.get()).containsEntry("message", "At least one "
|
|
||||||
+ RegistrarContact.Type.TECH.getDisplayName() + " contact must have a phone number");
|
+ RegistrarContact.Type.TECH.getDisplayName() + " contact must have a phone number");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
// Copyright 2016 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.ui.server.registrar;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static google.registry.testing.TaskQueueHelper.assertNoTasksEnqueued;
|
||||||
|
import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued;
|
||||||
|
import static google.registry.util.ResourceUtils.readResourceUtf8;
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
import static org.mockito.Mockito.anyInt;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import google.registry.export.sheet.SyncRegistrarsSheetAction;
|
||||||
|
import google.registry.model.registrar.Registrar;
|
||||||
|
import google.registry.testing.ExceptionRule;
|
||||||
|
import google.registry.testing.TaskQueueHelper.TaskMatcher;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.mail.internet.InternetAddress;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
/** Tests for {@link RegistrarAction}. */
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class RegistrarActionTest extends RegistrarActionTestCase {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final ExceptionRule thrown = new ExceptionRule();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSuccess_updateRegistrarInfo_andSendsNotificationEmail() throws Exception {
|
||||||
|
String expectedEmailBody = readResourceUtf8(getClass(), "testdata/update_registrar_email.txt");
|
||||||
|
action.handleJsonRequest(readJsonFromFile("testdata/update_registrar.json"));
|
||||||
|
verify(rsp, never()).setStatus(anyInt());
|
||||||
|
verify(emailService).createMessage();
|
||||||
|
verify(emailService).sendMessage(message);
|
||||||
|
assertThat(message.getAllRecipients()).asList().containsExactly(
|
||||||
|
new InternetAddress("notification@test.example"),
|
||||||
|
new InternetAddress("notification2@test.example"));
|
||||||
|
assertThat(message.getContent()).isEqualTo(expectedEmailBody);
|
||||||
|
assertTasksEnqueued("sheet", new TaskMatcher()
|
||||||
|
.url(SyncRegistrarsSheetAction.PATH)
|
||||||
|
.method("GET")
|
||||||
|
.header("Host", "backend.hostname"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFailure_updateRegistrarInfo_duplicateContacts() throws Exception {
|
||||||
|
Map<String, Object> response = action.handleJsonRequest(
|
||||||
|
readJsonFromFile("testdata/update_registrar_duplicate_contacts.json"));
|
||||||
|
assertThat(response).containsEntry("status", "ERROR");
|
||||||
|
assertThat((String) response.get("message")).startsWith("One email address");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRead_notAuthorized_failure() throws Exception {
|
||||||
|
when(sessionUtils.checkRegistrarConsoleLogin(req)).thenReturn(false);
|
||||||
|
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of());
|
||||||
|
assertThat(response).containsEntry("status", "ERROR");
|
||||||
|
assertThat((String) response.get("message")).startsWith("Not authorized");
|
||||||
|
assertNoTasksEnqueued("sheet");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the default read test for the registrar settings actions.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testRead_authorized_returnsRegistrarJson() throws Exception {
|
||||||
|
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of());
|
||||||
|
assertThat(response).containsEntry("status", "SUCCESS");
|
||||||
|
assertThat(response).containsEntry("results", asList(
|
||||||
|
Registrar.loadByClientId(CLIENT_ID).toJsonMap()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdate_emptyJsonObject_errorEmailFieldRequired() throws Exception {
|
||||||
|
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
|
||||||
|
"op", "update",
|
||||||
|
"args", ImmutableMap.of()));
|
||||||
|
assertThat(response).containsEntry("status", "ERROR");
|
||||||
|
assertThat(response).containsEntry("field", "emailAddress");
|
||||||
|
assertThat(response).containsEntry("message", "This field is required.");
|
||||||
|
assertNoTasksEnqueued("sheet");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdate_badEmail_errorEmailField() throws Exception {
|
||||||
|
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
|
||||||
|
"op", "update",
|
||||||
|
"args", ImmutableMap.of(
|
||||||
|
"emailAddress", "lolcat")));
|
||||||
|
assertThat(response).containsEntry("status", "ERROR");
|
||||||
|
assertThat(response).containsEntry("field", "emailAddress");
|
||||||
|
assertThat(response).containsEntry("message", "Please enter a valid email address.");
|
||||||
|
assertNoTasksEnqueued("sheet");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPost_nonAsciiCharacters_getsAngry() throws Exception {
|
||||||
|
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
|
||||||
|
"op", "update",
|
||||||
|
"args", ImmutableMap.of(
|
||||||
|
"emailAddress", "ヘ(◕。◕ヘ)@example.com")));
|
||||||
|
assertThat(response).containsEntry("status", "ERROR");
|
||||||
|
assertThat(response).containsEntry("field", "emailAddress");
|
||||||
|
assertThat(response).containsEntry("message", "Please only use ASCII-US characters.");
|
||||||
|
assertNoTasksEnqueued("sheet");
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,14 +17,20 @@ package google.registry.ui.server.registrar;
|
||||||
import static google.registry.security.JsonHttpTestUtils.createJsonPayload;
|
import static google.registry.security.JsonHttpTestUtils.createJsonPayload;
|
||||||
import static google.registry.security.JsonHttpTestUtils.createJsonResponseSupplier;
|
import static google.registry.security.JsonHttpTestUtils.createJsonResponseSupplier;
|
||||||
import static google.registry.security.XsrfTokenManager.generateToken;
|
import static google.registry.security.XsrfTokenManager.generateToken;
|
||||||
|
import static google.registry.util.ResourceUtils.readResourceUtf8;
|
||||||
import static org.mockito.Matchers.eq;
|
import static org.mockito.Matchers.eq;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import com.google.appengine.api.modules.ModulesService;
|
import com.google.appengine.api.modules.ModulesService;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import google.registry.export.sheet.SyncRegistrarsSheetAction;
|
import google.registry.export.sheet.SyncRegistrarsSheetAction;
|
||||||
import google.registry.model.ofy.Ofy;
|
import google.registry.model.ofy.Ofy;
|
||||||
|
import google.registry.model.registrar.Registrar;
|
||||||
|
import google.registry.request.JsonActionRunner;
|
||||||
|
import google.registry.request.JsonResponse;
|
||||||
|
import google.registry.request.ResponseImpl;
|
||||||
import google.registry.testing.AppEngineRule;
|
import google.registry.testing.AppEngineRule;
|
||||||
import google.registry.testing.ExceptionRule;
|
import google.registry.testing.ExceptionRule;
|
||||||
import google.registry.testing.FakeClock;
|
import google.registry.testing.FakeClock;
|
||||||
|
@ -41,15 +47,17 @@ import javax.mail.internet.MimeMessage;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
import org.json.simple.JSONValue;
|
||||||
|
import org.json.simple.parser.ParseException;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
/** Base class for tests using {@link RegistrarServlet}. */
|
/** Base class for tests using {@link RegistrarAction}. */
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class RegistrarServletTestCase {
|
public class RegistrarActionTestCase {
|
||||||
|
|
||||||
static final String CLIENT_ID = "TheRegistrar";
|
static final String CLIENT_ID = "TheRegistrar";
|
||||||
|
|
||||||
|
@ -71,26 +79,32 @@ public class RegistrarServletTestCase {
|
||||||
@Mock
|
@Mock
|
||||||
HttpServletResponse rsp;
|
HttpServletResponse rsp;
|
||||||
|
|
||||||
@Mock
|
|
||||||
SessionUtils sessionUtils;
|
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
SendEmailService emailService;
|
SendEmailService emailService;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
ModulesService modulesService;
|
ModulesService modulesService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
SessionUtils sessionUtils;
|
||||||
|
|
||||||
Message message;
|
Message message;
|
||||||
|
|
||||||
final RegistrarServlet servlet = new RegistrarServlet();
|
final RegistrarAction action = new RegistrarAction();
|
||||||
final StringWriter writer = new StringWriter();
|
final StringWriter writer = new StringWriter();
|
||||||
final Supplier<Map<String, Object>> json = createJsonResponseSupplier(writer);
|
final Supplier<Map<String, Object>> json = createJsonResponseSupplier(writer);
|
||||||
final FakeClock clock = new FakeClock(DateTime.parse("2014-01-01T00:00:00Z"));
|
final FakeClock clock = new FakeClock(DateTime.parse("2014-01-01T00:00:00Z"));
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
|
action.request = req;
|
||||||
|
action.sessionUtils = sessionUtils;
|
||||||
|
action.initialRegistrar = Registrar.loadByClientId(CLIENT_ID);
|
||||||
|
action.jsonActionRunner = new JsonActionRunner(
|
||||||
|
ImmutableMap.<String, Object>of(), new JsonResponse(new ResponseImpl(rsp)));
|
||||||
|
action.registrarChangesNotificationEmailAddresses = ImmutableList.of(
|
||||||
|
"notification@test.example", "notification2@test.example");
|
||||||
inject.setStaticField(Ofy.class, "clock", clock);
|
inject.setStaticField(Ofy.class, "clock", clock);
|
||||||
inject.setStaticField(ResourceServlet.class, "sessionUtils", sessionUtils);
|
|
||||||
inject.setStaticField(SendEmailUtils.class, "emailService", emailService);
|
inject.setStaticField(SendEmailUtils.class, "emailService", emailService);
|
||||||
inject.setStaticField(SyncRegistrarsSheetAction.class, "modulesService", modulesService);
|
inject.setStaticField(SyncRegistrarsSheetAction.class, "modulesService", modulesService);
|
||||||
message = new MimeMessage(Session.getDefaultInstance(new Properties(), null));
|
message = new MimeMessage(Session.getDefaultInstance(new Properties(), null));
|
||||||
|
@ -105,4 +119,13 @@ public class RegistrarServletTestCase {
|
||||||
when(sessionUtils.getRegistrarClientId(req)).thenReturn(CLIENT_ID);
|
when(sessionUtils.getRegistrarClientId(req)).thenReturn(CLIENT_ID);
|
||||||
when(modulesService.getVersionHostname("backend", null)).thenReturn("backend.hostname");
|
when(modulesService.getVersionHostname("backend", null)).thenReturn("backend.hostname");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Map<String, Object> readJsonFromFile(String filename) {
|
||||||
|
String contents = readResourceUtf8(getClass(), filename);
|
||||||
|
try {
|
||||||
|
return (Map<String, Object>) JSONValue.parseWithException(contents);
|
||||||
|
} catch (ParseException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,168 +0,0 @@
|
||||||
// Copyright 2016 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.ui.server.registrar;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
|
||||||
import static google.registry.security.JsonHttpTestUtils.createJsonPayload;
|
|
||||||
import static google.registry.testing.TaskQueueHelper.assertNoTasksEnqueued;
|
|
||||||
import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued;
|
|
||||||
import static google.registry.util.ResourceUtils.readResourceUtf8;
|
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import static javax.servlet.http.HttpServletResponse.SC_OK;
|
|
||||||
import static org.mockito.Matchers.eq;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
import google.registry.export.sheet.SyncRegistrarsSheetAction;
|
|
||||||
import google.registry.model.registrar.Registrar;
|
|
||||||
import google.registry.testing.TaskQueueHelper.TaskMatcher;
|
|
||||||
import javax.mail.internet.InternetAddress;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
|
||||||
|
|
||||||
/** Tests for {@link RegistrarServlet}. */
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
|
||||||
public class RegistrarServletTest extends RegistrarServletTestCase {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSuccess_updateRegistrarInfo_andSendsNotificationEmail() throws Exception {
|
|
||||||
String jsonPostData = readResourceUtf8(getClass(), "testdata/update_registrar.json");
|
|
||||||
String expectedEmailBody = readResourceUtf8(getClass(), "testdata/update_registrar_email.txt");
|
|
||||||
when(req.getReader()).thenReturn(createJsonPayload(jsonPostData));
|
|
||||||
servlet.service(req, rsp);
|
|
||||||
verify(rsp).setStatus(SC_OK);
|
|
||||||
verify(emailService).createMessage();
|
|
||||||
verify(emailService).sendMessage(message);
|
|
||||||
assertThat(message.getAllRecipients()).asList().containsExactly(
|
|
||||||
new InternetAddress("notification@test.example"),
|
|
||||||
new InternetAddress("notification2@test.example"));
|
|
||||||
assertThat(message.getContent()).isEqualTo(expectedEmailBody);
|
|
||||||
assertTasksEnqueued("sheet", new TaskMatcher()
|
|
||||||
.url(SyncRegistrarsSheetAction.PATH)
|
|
||||||
.method("GET")
|
|
||||||
.header("Host", "backend.hostname"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFailure_updateRegistrarInfo_duplicateContacts() throws Exception {
|
|
||||||
String jsonPostData =
|
|
||||||
readResourceUtf8(getClass(), "testdata/update_registrar_duplicate_contacts.json");
|
|
||||||
when(req.getReader()).thenReturn(createJsonPayload(jsonPostData));
|
|
||||||
servlet.service(req, rsp);
|
|
||||||
assertThat(json.get()).containsEntry("status", "ERROR");
|
|
||||||
assertThat((String) json.get().get("message")).startsWith("One email address");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRead_missingXsrfToken_failure() throws Exception {
|
|
||||||
when(req.getHeader(eq("X-CSRF-Token"))).thenReturn("");
|
|
||||||
servlet.service(req, rsp);
|
|
||||||
verify(rsp).sendError(403, "Invalid X-CSRF-Token");
|
|
||||||
assertNoTasksEnqueued("sheet");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRead_invalidXsrfToken_failure() throws Exception {
|
|
||||||
when(req.getHeader(eq("X-CSRF-Token"))).thenReturn("humbug");
|
|
||||||
servlet.service(req, rsp);
|
|
||||||
verify(rsp).sendError(403, "Invalid X-CSRF-Token");
|
|
||||||
assertNoTasksEnqueued("sheet");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRead_notLoggedIn_failure() throws Exception {
|
|
||||||
when(sessionUtils.isLoggedIn()).thenReturn(false);
|
|
||||||
servlet.service(req, rsp);
|
|
||||||
assertThat(json.get()).containsEntry("status", "ERROR");
|
|
||||||
assertThat(json.get()).containsEntry("message", "Not logged in");
|
|
||||||
assertNoTasksEnqueued("sheet");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRead_notAuthorized_failure() throws Exception {
|
|
||||||
when(sessionUtils.checkRegistrarConsoleLogin(req)).thenReturn(false);
|
|
||||||
servlet.service(req, rsp);
|
|
||||||
assertThat(json.get()).containsEntry("status", "ERROR");
|
|
||||||
assertThat((String) json.get().get("message")).startsWith("Not authorized");
|
|
||||||
assertNoTasksEnqueued("sheet");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRead_emptyPayload_failure() throws Exception {
|
|
||||||
when(req.getReader()).thenReturn(createJsonPayload(""));
|
|
||||||
servlet.service(req, rsp);
|
|
||||||
verify(rsp).sendError(400, "Malformed JSON");
|
|
||||||
assertNoTasksEnqueued("sheet");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the default read test for the registrar settings servlets.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testRead_authorized_returnsRegistrarJson() throws Exception {
|
|
||||||
servlet.service(req, rsp);
|
|
||||||
assertThat(json.get()).containsEntry("status", "SUCCESS");
|
|
||||||
assertThat(json.get()).containsEntry("results", asList(
|
|
||||||
Registrar.loadByClientId(CLIENT_ID).toJsonMap()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRead_authorized_nilClientId_failure() throws Exception {
|
|
||||||
String nilClientId = "doesnotexist";
|
|
||||||
when(sessionUtils.getRegistrarClientId(req)).thenReturn(nilClientId);
|
|
||||||
servlet.service(req, rsp);
|
|
||||||
verify(rsp).sendError(404, "No registrar exists with the given client id: " + nilClientId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdate_emptyJsonObject_errorEmailFieldRequired() throws Exception {
|
|
||||||
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
|
|
||||||
"op", "update",
|
|
||||||
"args", ImmutableMap.of())));
|
|
||||||
servlet.service(req, rsp);
|
|
||||||
assertThat(json.get()).containsEntry("status", "ERROR");
|
|
||||||
assertThat(json.get()).containsEntry("field", "emailAddress");
|
|
||||||
assertThat(json.get()).containsEntry("message", "This field is required.");
|
|
||||||
assertNoTasksEnqueued("sheet");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdate_badEmail_errorEmailField() throws Exception {
|
|
||||||
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
|
|
||||||
"op", "update",
|
|
||||||
"args", ImmutableMap.of(
|
|
||||||
"emailAddress", "lolcat"))));
|
|
||||||
servlet.service(req, rsp);
|
|
||||||
assertThat(json.get()).containsEntry("status", "ERROR");
|
|
||||||
assertThat(json.get()).containsEntry("field", "emailAddress");
|
|
||||||
assertThat(json.get()).containsEntry("message", "Please enter a valid email address.");
|
|
||||||
assertNoTasksEnqueued("sheet");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPost_nonAsciiCharacters_getsAngry() throws Exception {
|
|
||||||
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
|
|
||||||
"op", "update",
|
|
||||||
"args", ImmutableMap.of(
|
|
||||||
"emailAddress", "ヘ(◕。◕ヘ)@example.com"))));
|
|
||||||
servlet.service(req, rsp);
|
|
||||||
assertThat(json.get()).containsEntry("status", "ERROR");
|
|
||||||
assertThat(json.get()).containsEntry("field", "emailAddress");
|
|
||||||
assertThat(json.get()).containsEntry("message", "Please only use ASCII-US characters.");
|
|
||||||
assertNoTasksEnqueued("sheet");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -15,15 +15,12 @@
|
||||||
package google.registry.ui.server.registrar;
|
package google.registry.ui.server.registrar;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static google.registry.security.JsonHttpTestUtils.createJsonPayload;
|
|
||||||
import static google.registry.testing.CertificateSamples.SAMPLE_CERT;
|
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.CertificateSamples.SAMPLE_CERT2_HASH;
|
import static google.registry.testing.CertificateSamples.SAMPLE_CERT2_HASH;
|
||||||
import static google.registry.testing.CertificateSamples.SAMPLE_CERT_HASH;
|
import static google.registry.testing.CertificateSamples.SAMPLE_CERT_HASH;
|
||||||
import static google.registry.testing.DatastoreHelper.persistResource;
|
|
||||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import google.registry.config.RegistryEnvironment;
|
import google.registry.config.RegistryEnvironment;
|
||||||
|
@ -34,31 +31,30 @@ import org.junit.runner.RunWith;
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for security_settings.js use of {@link RegistrarServlet}.
|
* Unit tests for security_settings.js use of {@link RegistrarAction}.
|
||||||
*
|
*
|
||||||
* <p>The default read and session validation tests are handled by the
|
* <p>The default read and session validation tests are handled by the
|
||||||
* superclass.
|
* superclass.
|
||||||
*/
|
*/
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class SecuritySettingsTest extends RegistrarServletTestCase {
|
public class SecuritySettingsTest extends RegistrarActionTestCase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPost_updateCert_success() throws Exception {
|
public void testPost_updateCert_success() throws Exception {
|
||||||
Registrar modified = Registrar.loadByClientId(CLIENT_ID).asBuilder()
|
Registrar modified = Registrar.loadByClientId(CLIENT_ID).asBuilder()
|
||||||
.setClientCertificate(SAMPLE_CERT, clock.nowUtc())
|
.setClientCertificate(SAMPLE_CERT, clock.nowUtc())
|
||||||
.build();
|
.build();
|
||||||
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
|
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
|
||||||
"op", "update",
|
"op", "update",
|
||||||
"args", modified.toJsonMap())));
|
"args", modified.toJsonMap()));
|
||||||
servlet.service(req, rsp);
|
|
||||||
// Empty whoisServer and referralUrl fields should be set to defaults by server.
|
// Empty whoisServer and referralUrl fields should be set to defaults by server.
|
||||||
modified = modified.asBuilder()
|
modified = modified.asBuilder()
|
||||||
.setWhoisServer(RegistryEnvironment.get().config().getRegistrarDefaultWhoisServer())
|
.setWhoisServer(RegistryEnvironment.get().config().getRegistrarDefaultWhoisServer())
|
||||||
.setReferralUrl(
|
.setReferralUrl(
|
||||||
RegistryEnvironment.get().config().getRegistrarDefaultReferralUrl().toString())
|
RegistryEnvironment.get().config().getRegistrarDefaultReferralUrl().toString())
|
||||||
.build();
|
.build();
|
||||||
assertThat(json.get()).containsEntry("status", "SUCCESS");
|
assertThat(response).containsEntry("status", "SUCCESS");
|
||||||
assertThat(json.get()).containsEntry("results", asList(modified.toJsonMap()));
|
assertThat(response).containsEntry("results", asList(modified.toJsonMap()));
|
||||||
assertThat(Registrar.loadByClientId(CLIENT_ID)).isEqualTo(modified);
|
assertThat(Registrar.loadByClientId(CLIENT_ID)).isEqualTo(modified);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,12 +62,11 @@ public class SecuritySettingsTest extends RegistrarServletTestCase {
|
||||||
public void testPost_updateCert_failure() throws Exception {
|
public void testPost_updateCert_failure() throws Exception {
|
||||||
Map<String, Object> reqJson = Registrar.loadByClientId(CLIENT_ID).toJsonMap();
|
Map<String, Object> reqJson = Registrar.loadByClientId(CLIENT_ID).toJsonMap();
|
||||||
reqJson.put("clientCertificate", "BLAH");
|
reqJson.put("clientCertificate", "BLAH");
|
||||||
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
|
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
|
||||||
"op", "update",
|
"op", "update",
|
||||||
"args", reqJson)));
|
"args", reqJson));
|
||||||
servlet.service(req, rsp);
|
assertThat(response).containsEntry("status", "ERROR");
|
||||||
assertThat(json.get()).containsEntry("status", "ERROR");
|
assertThat(response).containsEntry("message", "Invalid X.509 PEM certificate");
|
||||||
assertThat(json.get()).containsEntry("message", "Invalid X.509 PEM certificate");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -79,10 +74,9 @@ public class SecuritySettingsTest extends RegistrarServletTestCase {
|
||||||
Map<String, Object> jsonMap = Registrar.loadByClientId(CLIENT_ID).toJsonMap();
|
Map<String, Object> jsonMap = Registrar.loadByClientId(CLIENT_ID).toJsonMap();
|
||||||
jsonMap.put("clientCertificate", SAMPLE_CERT);
|
jsonMap.put("clientCertificate", SAMPLE_CERT);
|
||||||
jsonMap.put("failoverClientCertificate", null);
|
jsonMap.put("failoverClientCertificate", null);
|
||||||
when(req.getReader()).thenReturn(
|
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
|
||||||
createJsonPayload(ImmutableMap.of("op", "update", "args", jsonMap)));
|
"op", "update", "args", jsonMap));
|
||||||
servlet.service(req, rsp);
|
assertThat(response).containsEntry("status", "SUCCESS");
|
||||||
assertThat(json.get()).containsEntry("status", "SUCCESS");
|
|
||||||
Registrar registrar = Registrar.loadByClientId(CLIENT_ID);
|
Registrar registrar = Registrar.loadByClientId(CLIENT_ID);
|
||||||
assertThat(registrar.getClientCertificate()).isEqualTo(SAMPLE_CERT);
|
assertThat(registrar.getClientCertificate()).isEqualTo(SAMPLE_CERT);
|
||||||
assertThat(registrar.getClientCertificateHash()).isEqualTo(SAMPLE_CERT_HASH);
|
assertThat(registrar.getClientCertificateHash()).isEqualTo(SAMPLE_CERT_HASH);
|
||||||
|
@ -94,10 +88,9 @@ public class SecuritySettingsTest extends RegistrarServletTestCase {
|
||||||
public void testChangeFailoverCertificate() throws Exception {
|
public void testChangeFailoverCertificate() throws Exception {
|
||||||
Map<String, Object> jsonMap = Registrar.loadByClientId(CLIENT_ID).toJsonMap();
|
Map<String, Object> jsonMap = Registrar.loadByClientId(CLIENT_ID).toJsonMap();
|
||||||
jsonMap.put("failoverClientCertificate", SAMPLE_CERT2);
|
jsonMap.put("failoverClientCertificate", SAMPLE_CERT2);
|
||||||
when(req.getReader()).thenReturn(
|
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
|
||||||
createJsonPayload(ImmutableMap.of("op", "update", "args", jsonMap)));
|
"op", "update", "args", jsonMap));
|
||||||
servlet.service(req, rsp);
|
assertThat(response).containsEntry("status", "SUCCESS");
|
||||||
assertThat(json.get()).containsEntry("status", "SUCCESS");
|
|
||||||
Registrar registrar = Registrar.loadByClientId(CLIENT_ID);
|
Registrar registrar = Registrar.loadByClientId(CLIENT_ID);
|
||||||
assertThat(registrar.getFailoverClientCertificate()).isEqualTo(SAMPLE_CERT2);
|
assertThat(registrar.getFailoverClientCertificate()).isEqualTo(SAMPLE_CERT2);
|
||||||
assertThat(registrar.getFailoverClientCertificateHash()).isEqualTo(SAMPLE_CERT2_HASH);
|
assertThat(registrar.getFailoverClientCertificateHash()).isEqualTo(SAMPLE_CERT2_HASH);
|
||||||
|
@ -105,18 +98,17 @@ public class SecuritySettingsTest extends RegistrarServletTestCase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEmptyOrNullCertificate_doesNotClearOutCurrentOne() throws Exception {
|
public void testEmptyOrNullCertificate_doesNotClearOutCurrentOne() throws Exception {
|
||||||
persistResource(
|
action.initialRegistrar =
|
||||||
Registrar.loadByClientId(CLIENT_ID).asBuilder()
|
Registrar.loadByClientId(CLIENT_ID).asBuilder()
|
||||||
.setClientCertificate(SAMPLE_CERT, START_OF_TIME)
|
.setClientCertificate(SAMPLE_CERT, START_OF_TIME)
|
||||||
.setFailoverClientCertificate(SAMPLE_CERT2, START_OF_TIME)
|
.setFailoverClientCertificate(SAMPLE_CERT2, START_OF_TIME)
|
||||||
.build());
|
.build();
|
||||||
Map<String, Object> jsonMap = Registrar.loadByClientId(CLIENT_ID).toJsonMap();
|
Map<String, Object> jsonMap = action.initialRegistrar.toJsonMap();
|
||||||
jsonMap.put("clientCertificate", null);
|
jsonMap.put("clientCertificate", null);
|
||||||
jsonMap.put("failoverClientCertificate", "");
|
jsonMap.put("failoverClientCertificate", "");
|
||||||
when(req.getReader()).thenReturn(
|
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
|
||||||
createJsonPayload(ImmutableMap.of("op", "update", "args", jsonMap)));
|
"op", "update", "args", jsonMap));
|
||||||
servlet.service(req, rsp);
|
assertThat(response).containsEntry("status", "SUCCESS");
|
||||||
assertThat(json.get()).containsEntry("status", "SUCCESS");
|
|
||||||
Registrar registrar = Registrar.loadByClientId(CLIENT_ID);
|
Registrar registrar = Registrar.loadByClientId(CLIENT_ID);
|
||||||
assertThat(registrar.getClientCertificate()).isEqualTo(SAMPLE_CERT);
|
assertThat(registrar.getClientCertificate()).isEqualTo(SAMPLE_CERT);
|
||||||
assertThat(registrar.getClientCertificateHash()).isEqualTo(SAMPLE_CERT_HASH);
|
assertThat(registrar.getClientCertificateHash()).isEqualTo(SAMPLE_CERT_HASH);
|
||||||
|
|
|
@ -16,25 +16,24 @@ package google.registry.ui.server.registrar;
|
||||||
|
|
||||||
import static com.google.common.base.Strings.repeat;
|
import static com.google.common.base.Strings.repeat;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static google.registry.security.JsonHttpTestUtils.createJsonPayload;
|
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import google.registry.model.registrar.Registrar;
|
import google.registry.model.registrar.Registrar;
|
||||||
import google.registry.model.registrar.RegistrarAddress;
|
import google.registry.model.registrar.RegistrarAddress;
|
||||||
|
import java.util.Map;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for security_settings.js use of {@link RegistrarServlet}.
|
* Unit tests for security_settings.js use of {@link RegistrarAction}.
|
||||||
*
|
*
|
||||||
* <p>The default read and session validation tests are handled by the superclass.
|
* <p>The default read and session validation tests are handled by the superclass.
|
||||||
*/
|
*/
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class WhoisSettingsTest extends RegistrarServletTestCase {
|
public class WhoisSettingsTest extends RegistrarActionTestCase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPost_update_success() throws Exception {
|
public void testPost_update_success() throws Exception {
|
||||||
|
@ -52,12 +51,11 @@ public class WhoisSettingsTest extends RegistrarServletTestCase {
|
||||||
.setCountryCode("US")
|
.setCountryCode("US")
|
||||||
.build())
|
.build())
|
||||||
.build();
|
.build();
|
||||||
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
|
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
|
||||||
"op", "update",
|
"op", "update",
|
||||||
"args", modified.toJsonMap())));
|
"args", modified.toJsonMap()));
|
||||||
servlet.service(req, rsp);
|
assertThat(response.get("status")).isEqualTo("SUCCESS");
|
||||||
assertThat(json.get().get("status")).isEqualTo("SUCCESS");
|
assertThat(response.get("results")).isEqualTo(asList(modified.toJsonMap()));
|
||||||
assertThat(json.get().get("results")).isEqualTo(asList(modified.toJsonMap()));
|
|
||||||
assertThat(Registrar.loadByClientId(CLIENT_ID)).isEqualTo(modified);
|
assertThat(Registrar.loadByClientId(CLIENT_ID)).isEqualTo(modified);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,13 +73,12 @@ public class WhoisSettingsTest extends RegistrarServletTestCase {
|
||||||
.setCountryCode("US")
|
.setCountryCode("US")
|
||||||
.build())
|
.build())
|
||||||
.build();
|
.build();
|
||||||
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
|
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
|
||||||
"op", "update",
|
"op", "update",
|
||||||
"args", modified.toJsonMap())));
|
"args", modified.toJsonMap()));
|
||||||
servlet.service(req, rsp);
|
assertThat(response.get("status")).isEqualTo("ERROR");
|
||||||
assertThat(json.get().get("status")).isEqualTo("ERROR");
|
assertThat(response.get("field")).isEqualTo("localizedAddress.state");
|
||||||
assertThat(json.get().get("field")).isEqualTo("localizedAddress.state");
|
assertThat(response.get("message")).isEqualTo("Unknown US state code.");
|
||||||
assertThat(json.get().get("message")).isEqualTo("Unknown US state code.");
|
|
||||||
assertThat(Registrar.loadByClientId(CLIENT_ID)).isNotEqualTo(modified);
|
assertThat(Registrar.loadByClientId(CLIENT_ID)).isNotEqualTo(modified);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,13 +96,12 @@ public class WhoisSettingsTest extends RegistrarServletTestCase {
|
||||||
.setCountryCode("US")
|
.setCountryCode("US")
|
||||||
.build())
|
.build())
|
||||||
.build();
|
.build();
|
||||||
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
|
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
|
||||||
"op", "update",
|
"op", "update",
|
||||||
"args", modified.toJsonMap())));
|
"args", modified.toJsonMap()));
|
||||||
servlet.service(req, rsp);
|
assertThat(response.get("status")).isEqualTo("ERROR");
|
||||||
assertThat(json.get().get("status")).isEqualTo("ERROR");
|
assertThat(response.get("field")).isEqualTo("localizedAddress.street[1]");
|
||||||
assertThat(json.get().get("field")).isEqualTo("localizedAddress.street[1]");
|
assertThat((String) response.get("message"))
|
||||||
assertThat((String) json.get().get("message"))
|
|
||||||
.contains("Number of characters (600) not in range");
|
.contains("Number of characters (600) not in range");
|
||||||
assertThat(Registrar.loadByClientId(CLIENT_ID)).isNotEqualTo(modified);
|
assertThat(Registrar.loadByClientId(CLIENT_ID)).isNotEqualTo(modified);
|
||||||
}
|
}
|
||||||
|
@ -115,13 +111,12 @@ public class WhoisSettingsTest extends RegistrarServletTestCase {
|
||||||
Registrar modified = Registrar.loadByClientId(CLIENT_ID).asBuilder()
|
Registrar modified = Registrar.loadByClientId(CLIENT_ID).asBuilder()
|
||||||
.setWhoisServer("tears@dry.tragical.lol")
|
.setWhoisServer("tears@dry.tragical.lol")
|
||||||
.build();
|
.build();
|
||||||
when(req.getReader()).thenReturn(createJsonPayload(ImmutableMap.of(
|
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
|
||||||
"op", "update",
|
"op", "update",
|
||||||
"args", modified.toJsonMap())));
|
"args", modified.toJsonMap()));
|
||||||
servlet.service(req, rsp);
|
assertThat(response.get("status")).isEqualTo("ERROR");
|
||||||
assertThat(json.get().get("status")).isEqualTo("ERROR");
|
assertThat(response.get("field")).isEqualTo("whoisServer");
|
||||||
assertThat(json.get().get("field")).isEqualTo("whoisServer");
|
assertThat(response.get("message")).isEqualTo("Not a valid hostname.");
|
||||||
assertThat(json.get().get("message")).isEqualTo("Not a valid hostname.");
|
|
||||||
assertThat(Registrar.loadByClientId(CLIENT_ID)).isNotEqualTo(modified);
|
assertThat(Registrar.loadByClientId(CLIENT_ID)).isNotEqualTo(modified);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue