mv com/google/domain/registry google/registry

This change renames directories in preparation for the great package
rename. The repository is now in a broken state because the code
itself hasn't been updated. However this should ensure that git
correctly preserves history for each file.
This commit is contained in:
Justine Tunney 2016-05-13 18:55:08 -04:00
parent a41677aea1
commit 5012893c1d
2396 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,56 @@
package(
default_visibility = ["//java/com/google/domain/registry:registry_project"],
)
load("//java/com/google/testing/builddefs:GenTestRules.bzl", "GenTestRules")
java_library(
name = "security",
srcs = glob(
["*.java"],
exclude = glob(["*ServletTest.java"]),
),
deps = [
"//java/com/google/common/base",
"//java/com/google/common/collect",
"//java/com/google/common/net",
"//java/com/google/domain/registry/security",
"//java/com/google/domain/registry/util",
"//javatests/com/google/domain/registry/testing",
"//third_party/java/appengine:appengine-api-testonly",
"//third_party/java/appengine:appengine-testing",
"//third_party/java/joda_time",
"//third_party/java/json_simple",
"//third_party/java/junit",
"//third_party/java/mockito",
"//third_party/java/servlet/servlet_api",
"//third_party/java/truth",
],
)
java_library(
name = "servlets",
srcs = glob(["*ServletTest.java"]),
deps = [
"//java/com/google/common/collect",
"//java/com/google/common/net",
"//java/com/google/domain/registry/request",
"//java/com/google/domain/registry/security",
"//java/com/google/domain/registry/security:servlets",
"//javatests/com/google/domain/registry/testing",
"//third_party/java/junit",
"//third_party/java/mockito",
"//third_party/java/servlet/servlet_api",
"//third_party/java/truth",
],
)
GenTestRules(
name = "GeneratedTestRules",
test_files = glob(["*Test.java"]),
deps = [
":security",
":servlets",
],
)

View file

@ -0,0 +1,136 @@
// Copyright 2016 The Domain Registry 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 com.google.domain.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.net.MediaType.PLAIN_TEXT_UTF_8;
import static com.google.common.truth.Truth.assertThat;
import static java.nio.charset.StandardCharsets.UTF_16;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableMap;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/** Unit tests for {@link JsonHttp}. */
@RunWith(MockitoJUnitRunner.class)
public class JsonHttpTest {
@Mock
HttpServletRequest req;
@Mock
HttpServletResponse rsp;
@Test
public void testRead_postMethod_works() throws Exception {
when(req.getMethod()).thenReturn("POST");
when(req.getContentType()).thenReturn(JSON_UTF_8.toString());
when(req.getReader()).thenReturn(new BufferedReader(new StringReader("{\"k\":\"v\"}")));
assertThat(JsonHttp.read(req)).containsEntry("k", "v");
}
@Test
public void testRead_putMethod_works() throws Exception {
when(req.getMethod()).thenReturn("PUT");
when(req.getContentType()).thenReturn(JSON_UTF_8.toString());
when(req.getReader()).thenReturn(new BufferedReader(new StringReader("{\"k\":\"v\"}")));
assertThat(JsonHttp.read(req)).containsEntry("k", "v");
}
@Test
public void testRead_getMethod_notAllowed() throws Exception {
when(req.getMethod()).thenReturn("GET");
when(req.getContentType()).thenReturn(JSON_UTF_8.toString());
when(req.getReader()).thenReturn(new BufferedReader(new StringReader("{}")));
assertThat(JsonHttp.read(req)).isNull();
}
@Test
public void testRead_textPlainContentType_notAllowed() throws Exception {
when(req.getMethod()).thenReturn("POST");
when(req.getContentType()).thenReturn(PLAIN_TEXT_UTF_8.toString());
when(req.getReader()).thenReturn(new BufferedReader(new StringReader("{\"k\":\"v\"}")));
assertThat(JsonHttp.read(req)).isNull();
}
@Test
public void testRead_jsonContentTypeWithoutCharsetParameter_allowed() throws Exception {
when(req.getMethod()).thenReturn("POST");
when(req.getContentType()).thenReturn(JSON_UTF_8.withoutParameters().toString());
when(req.getReader()).thenReturn(new BufferedReader(new StringReader("{\"k\":\"v\"}")));
assertThat(JsonHttp.read(req)).containsEntry("k", "v");
}
@Test
public void testRead_jsonContentTypeWithWeirdCharsetParameter_notAllowed() throws Exception {
when(req.getMethod()).thenReturn("POST");
when(req.getContentType()).thenReturn(JSON_UTF_8.withCharset(UTF_16).toString());
when(req.getReader()).thenReturn(new BufferedReader(new StringReader("{\"k\":\"v\"}")));
assertThat(JsonHttp.read(req)).isNull();
}
@Test
public void testRead_emptyJson_notAllowed() throws Exception {
when(req.getMethod()).thenReturn("POST");
when(req.getContentType()).thenReturn(JSON_UTF_8.toString());
when(req.getReader()).thenReturn(new BufferedReader(new StringReader("")));
assertThat(JsonHttp.read(req)).isNull();
}
@Test
public void testRead_nonObjectJson_notAllowed() throws Exception {
when(req.getMethod()).thenReturn("POST");
when(req.getContentType()).thenReturn(JSON_UTF_8.toString());
when(req.getReader()).thenReturn(new BufferedReader(new StringReader("123")));
assertThat(JsonHttp.read(req)).isNull();
}
@Test
public void testRead_nullJson_notAllowed() throws Exception {
when(req.getMethod()).thenReturn("POST");
when(req.getContentType()).thenReturn(JSON_UTF_8.toString());
when(req.getReader()).thenReturn(new BufferedReader(new StringReader("null")));
assertThat(JsonHttp.read(req)).isNull();
}
@Test
public void testWrite() throws Exception {
StringWriter writer = new StringWriter();
when(rsp.getWriter()).thenReturn(new PrintWriter(writer));
JsonHttp.write(rsp, ImmutableMap.of("k", "v"));
assertThat(writer.toString()).isEqualTo(")]}'\n{\"k\":\"v\"}");
verify(rsp).setHeader(CONTENT_DISPOSITION, "attachment");
verify(rsp).setHeader(X_CONTENT_TYPE_OPTIONS, "nosniff");
verify(rsp).setContentType(JSON_UTF_8.toString());
verify(rsp).getWriter();
verifyNoMoreInteractions(rsp);
}
}

View file

@ -0,0 +1,91 @@
// Copyright 2016 The Domain Registry 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 com.google.domain.registry.security;
import static com.google.common.base.Suppliers.memoize;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assert_;
import static com.google.domain.registry.security.JsonHttp.JSON_SAFETY_PREFIX;
import com.google.common.base.Supplier;
import org.json.simple.JSONValue;
import org.json.simple.parser.ParseException;
import java.io.BufferedReader;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Map;
/**
* Helper class for testing JSON RPC servlets.
*/
public final class JsonHttpTestUtils {
/** Returns JSON payload for mocked result of {@code rsp.getReader()}. */
public static BufferedReader createJsonPayload(Map<String, ?> object) {
return createJsonPayload(JSONValue.toJSONString(object));
}
/** @see #createJsonPayload(Map) */
public static BufferedReader createJsonPayload(String jsonText) {
return new BufferedReader(new StringReader(jsonText));
}
/**
* Returns JSON data parsed out of a JsonTransportServlet response stored in the given writer.
* If the data will be fetched multiple times, consider {@link #createJsonResponseSupplier}.
*
* <p>Example Mockito usage:<pre> {@code
*
* StringWriter writer = new StringWriter();
* when(rsp.getWriter()).thenReturn(new PrintWriter(writer));
* servlet.service(req, rsp);
* assertThat(getJsonResponse(writer)).containsEntry("status", "SUCCESS");}</pre>
*/
public static Map<String, Object> getJsonResponse(StringWriter writer) {
String jsonText = writer.toString();
assertThat(jsonText).startsWith(JSON_SAFETY_PREFIX);
jsonText = jsonText.substring(JSON_SAFETY_PREFIX.length());
try {
@SuppressWarnings("unchecked")
Map<String, Object> json = (Map<String, Object>) JSONValue.parseWithException(jsonText);
return json;
} catch (ClassCastException | ParseException e) {
assert_().fail("Bad JSON: %s\n%s", e.getMessage(), jsonText);
throw new AssertionError();
}
}
/**
* Returns a memoized supplier that'll provide the JSON response object of the tested servlet.
*
* <p>This works with Mockito as follows:<pre> {@code
*
* StringWriter writer = new StringWriter();
* Supplier<Map<String, Object>> json = createJsonResponseSupplier(writer);
* when(rsp.getWriter()).thenReturn(new PrintWriter(writer));
* servlet.service(req, rsp);
* assertThat(json.get()).containsEntry("status", "SUCCESS");}</pre>
*/
public static Supplier<Map<String, Object>> createJsonResponseSupplier(
final StringWriter writer) {
return memoize(new Supplier<Map<String, Object>>() {
@Override
public Map<String, Object> get() {
return getJsonResponse(writer);
}});
}
}

View file

@ -0,0 +1,159 @@
// Copyright 2016 The Domain Registry 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 com.google.domain.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 com.google.domain.registry.request.HttpException;
import com.google.domain.registry.testing.AppEngineRule;
import com.google.domain.registry.testing.ExceptionRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
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;
/** 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, "&lt;script&gt;");
}
}

View file

@ -0,0 +1,107 @@
// Copyright 2016 The Domain Registry 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 com.google.domain.registry.security;
import static com.google.domain.registry.security.XsrfTokenManager.X_CSRF_TOKEN;
import static com.google.domain.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 com.google.domain.registry.testing.AppEngineRule;
import com.google.domain.registry.testing.UserInfo;
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;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/** 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());
}
}

View file

@ -0,0 +1,96 @@
// Copyright 2016 The Domain Registry 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 com.google.domain.registry.security;
import static com.google.common.truth.Truth.assertThat;
import static com.google.domain.registry.security.XsrfTokenManager.generateToken;
import static com.google.domain.registry.security.XsrfTokenManager.validateToken;
import static com.google.domain.registry.util.DateTimeUtils.START_OF_TIME;
import com.google.common.base.Splitter;
import com.google.domain.registry.testing.AppEngineRule;
import com.google.domain.registry.testing.FakeClock;
import com.google.domain.registry.testing.InjectRule;
import com.google.domain.registry.testing.UserInfo;
import org.joda.time.Duration;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
/** Tests for {@link XsrfTokenManager}. */
@RunWith(MockitoJUnitRunner.class)
public class XsrfTokenManagerTest {
private static final Duration ONE_DAY = Duration.standardDays(1);
FakeClock clock = new FakeClock(START_OF_TIME);
@Rule
public final AppEngineRule appEngine = AppEngineRule.builder()
.withDatastore()
.withUserService(UserInfo.createAdmin("a@example.com", "user1"))
.build();
@Rule
public InjectRule inject = new InjectRule();
@Before
public void init() {
inject.setStaticField(XsrfTokenManager.class, "clock", clock);
}
@Test
public void testSuccess() {
assertThat(validateToken(generateToken("console"), "console", ONE_DAY)).isTrue();
}
@Test
public void testNoTimestamp() {
assertThat(validateToken("foo", "console", ONE_DAY)).isFalse();
}
@Test
public void testBadNumberTimestamp() {
assertThat(validateToken("foo:bar", "console", ONE_DAY)).isFalse();
}
@Test
public void testExpired() {
String token = generateToken("console");
clock.setTo(START_OF_TIME.plusDays(2));
assertThat(validateToken(token, "console", ONE_DAY)).isFalse();
}
@Test
public void testTimestampTamperedWith() {
String encodedPart = Splitter.on(':').splitToList(generateToken("console")).get(0);
long tamperedTimestamp = clock.nowUtc().plusMillis(1).getMillis();
assertThat(validateToken(encodedPart + ":" + tamperedTimestamp, "console", ONE_DAY)).isFalse();
}
@Test
public void testDifferentUser() {
assertThat(validateToken(generateToken("console", "b@example.com"), "console", ONE_DAY))
.isFalse();
}
@Test
public void testDifferentScope() {
assertThat(validateToken(generateToken("console"), "foobar", ONE_DAY)).isFalse();
}
}