mirror of
https://github.com/google/nomulus
synced 2026-06-09 16:33:02 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9479e1e8b9 | |||
| 110bd9c057 | |||
| 2ae5aba7ff | |||
| b878e5acc1 | |||
| 4d0409c924 | |||
| 0292887cb9 | |||
| 464f6ba90a | |||
| 0ab0a8c2e6 | |||
| 2cc4e5fa94 | |||
| 47a890253e | |||
| b452b0628d | |||
| 5dfd96d26d | |||
| e2a673d914 |
@@ -1,8 +1,8 @@
|
||||
# Nomulus
|
||||
|
||||
| Internal Build | FOSS Build | License | Code Search |
|
||||
|----------------|------------|---------|-------------|
|
||||
|[](https://storage.googleapis.com/domain-registry-kokoro/index.html)|[](https://travis-ci.org/google/nomulus)|[](https://github.com/google/nomulus/blob/master/LICENSE)|[](https://sourcegraph.com/github.com/google/nomulus)|
|
||||
| Internal Build | FOSS Build | LGTM | License | Code Search |
|
||||
|----------------|------------|------|---------|-------------|
|
||||
|[](https://storage.googleapis.com/domain-registry-kokoro/index.html)|[](https://travis-ci.org/google/nomulus)|[](https://lgtm.com/projects/g/google/nomulus/alerts/)|[](https://github.com/google/nomulus/blob/master/LICENSE)|[](https://sourcegraph.com/github.com/google/nomulus)|
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -75,6 +75,12 @@ if (project.path == ":services:default") {
|
||||
|
||||
appengine {
|
||||
deploy {
|
||||
// appengineDeployAll task requires the version to be set. So,
|
||||
// this config lets gcloud select a version name when deploying
|
||||
// to alpha from our workstation.
|
||||
if (environment != 'production' && environment != 'sandbox') {
|
||||
version = 'GCLOUD_CONFIG'
|
||||
}
|
||||
projectId = gcpProject
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
buildscript {
|
||||
if (project.disableDependencyLocking.toBoolean() == false) {
|
||||
if (rootProject.enableDependencyLocking.toBoolean()) {
|
||||
// Lock buildscript dependencies.
|
||||
configurations.classpath {
|
||||
resolutionStrategy.activateDependencyLocking()
|
||||
@@ -75,7 +75,7 @@ reportUploader {
|
||||
|
||||
apply from: 'dependencies.gradle'
|
||||
|
||||
apply from: 'dependency_license.gradle'
|
||||
apply from: 'dependency_lic.gradle'
|
||||
|
||||
// Custom task to run checkLicense in buildSrc, which is not triggered
|
||||
// by root project tasks. A shell task is used because buildSrc tasks
|
||||
@@ -169,7 +169,7 @@ subprojects {
|
||||
}
|
||||
}
|
||||
|
||||
if (rootProject.disableDependencyLocking.toBoolean() == false) {
|
||||
if (rootProject.enableDependencyLocking.toBoolean()) {
|
||||
buildscript {
|
||||
// Lock buildscript dependencies.
|
||||
configurations.classpath {
|
||||
@@ -177,7 +177,7 @@ subprojects {
|
||||
}
|
||||
}
|
||||
// Lock application dependencies except for the gradle-license-report
|
||||
// plugin. See dependency_license.gradle for more information.
|
||||
// plugin. See dependency_lic.gradle for more information.
|
||||
configurations.findAll { it.name != 'dependencyLicenseReport' }.each {
|
||||
it.resolutionStrategy.activateDependencyLocking()
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
buildscript {
|
||||
if (rootProject.disableDependencyLocking.toBoolean() == false) {
|
||||
if (project.enableDependencyLocking.toBoolean()) {
|
||||
// Lock buildscript dependencies.
|
||||
configurations.classpath {
|
||||
resolutionStrategy.activateDependencyLocking()
|
||||
@@ -32,7 +32,7 @@ plugins {
|
||||
id 'com.diffplug.gradle.spotless' version '3.18.0'
|
||||
}
|
||||
|
||||
if (rootProject.disableDependencyLocking.toBoolean() == false) {
|
||||
if (rootProject.enableDependencyLocking.toBoolean()) {
|
||||
// Lock application dependencies.
|
||||
dependencyLocking {
|
||||
lockAllConfigurations()
|
||||
@@ -52,7 +52,7 @@ repositories {
|
||||
}
|
||||
|
||||
apply from: '../dependencies.gradle'
|
||||
apply from: '../dependency_license.gradle'
|
||||
apply from: '../dependency_lic.gradle'
|
||||
apply from: '../java_common.gradle'
|
||||
|
||||
sourceSets {
|
||||
|
||||
@@ -1 +1 @@
|
||||
disableDependencyLocking=false
|
||||
enableDependencyLocking=false
|
||||
|
||||
@@ -16,6 +16,7 @@ package google.registry.config;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
|
||||
import com.google.auth.oauth2.GoogleCredentials;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import dagger.Module;
|
||||
@@ -68,6 +69,29 @@ public abstract class CredentialModule {
|
||||
return GoogleCredentialsBundle.create(credential);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the default {@link GoogleCredential} from the Google Cloud runtime for G Suite
|
||||
* Drive API.
|
||||
* TODO(b/138195359): Deprecate this credential once we figure out how to use
|
||||
* {@link GoogleCredentials} for G Suite Drive API.
|
||||
*/
|
||||
@GSuiteDriveCredential
|
||||
@Provides
|
||||
@Singleton
|
||||
public static GoogleCredential provideGSuiteDriveCredential(
|
||||
@Config("defaultCredentialOauthScopes") ImmutableList<String> requiredScopes) {
|
||||
GoogleCredential credential;
|
||||
try {
|
||||
credential = GoogleCredential.getApplicationDefault();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (credential.createScopedRequired()) {
|
||||
credential = credential.createScoped(requiredScopes);
|
||||
}
|
||||
return credential;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a {@link GoogleCredentialsBundle} from the service account's JSON key file.
|
||||
*
|
||||
@@ -118,6 +142,13 @@ public abstract class CredentialModule {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface DefaultCredential {}
|
||||
|
||||
|
||||
/** Dagger qualifier for the credential for G Suite Drive API. */
|
||||
@Qualifier
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface GSuiteDriveCredential {}
|
||||
|
||||
/**
|
||||
* Dagger qualifier for a credential from a service account's JSON key, to be used in non-request
|
||||
* threads.
|
||||
|
||||
@@ -894,9 +894,9 @@ public final class RegistryConfig {
|
||||
* @see google.registry.reporting.spec11.Spec11EmailUtils
|
||||
*/
|
||||
@Provides
|
||||
@Config("spec11ReplyToEmailAddress")
|
||||
public static InternetAddress provideSpec11ReplyToEmailAddress(RegistryConfigSettings config) {
|
||||
return parseEmailAddress(config.misc.spec11ReplyToEmailAddress);
|
||||
@Config("spec11OutgoingEmailAddress")
|
||||
public static InternetAddress provideSpec11OutgoingEmailAddress(RegistryConfigSettings config) {
|
||||
return parseEmailAddress(config.misc.spec11OutgoingEmailAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -173,7 +173,7 @@ public class RegistryConfigSettings {
|
||||
public static class Misc {
|
||||
public String sheetExportId;
|
||||
public String alertRecipientEmailAddress;
|
||||
public String spec11ReplyToEmailAddress;
|
||||
public String spec11OutgoingEmailAddress;
|
||||
public int asyncDeleteDelaySeconds;
|
||||
public int transientFailureRetries;
|
||||
}
|
||||
|
||||
@@ -357,9 +357,9 @@ misc:
|
||||
# Address we send alert summary emails to.
|
||||
alertRecipientEmailAddress: email@example.com
|
||||
|
||||
# Address to which the Spec 11 emails to registrars should be replied. This needs
|
||||
# to be a deliverable email address in case the registrars want to contact us.
|
||||
spec11ReplyToEmailAddress: reply-to@example.com
|
||||
# Address from which Spec 11 emails to registrars are sent. This needs
|
||||
# to be a deliverable email address to handle replies from registrars as well.
|
||||
spec11OutgoingEmailAddress: abuse@example.com
|
||||
|
||||
# How long to delay processing of asynchronous deletions. This should always
|
||||
# be longer than eppResourceCachingSeconds, to prevent deleted contacts or
|
||||
|
||||
@@ -14,16 +14,16 @@
|
||||
|
||||
package google.registry.export;
|
||||
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
|
||||
import com.google.api.services.drive.Drive;
|
||||
import dagger.Component;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import google.registry.config.CredentialModule;
|
||||
import google.registry.config.CredentialModule.DefaultCredential;
|
||||
import google.registry.config.CredentialModule.GSuiteDriveCredential;
|
||||
import google.registry.config.RegistryConfig.Config;
|
||||
import google.registry.config.RegistryConfig.ConfigModule;
|
||||
import google.registry.storage.drive.DriveConnection;
|
||||
import google.registry.util.GoogleCredentialsBundle;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
/** Dagger module for Google {@link Drive} service connection objects. */
|
||||
@@ -32,13 +32,13 @@ public final class DriveModule {
|
||||
|
||||
@Provides
|
||||
static Drive provideDrive(
|
||||
@DefaultCredential GoogleCredentialsBundle credentialsBundle,
|
||||
@GSuiteDriveCredential GoogleCredential googleCredential,
|
||||
@Config("projectId") String projectId) {
|
||||
|
||||
return new Drive.Builder(
|
||||
credentialsBundle.getHttpTransport(),
|
||||
credentialsBundle.getJsonFactory(),
|
||||
credentialsBundle.getHttpRequestInitializer())
|
||||
googleCredential.getTransport(),
|
||||
googleCredential.getJsonFactory(),
|
||||
googleCredential)
|
||||
.setApplicationName(projectId)
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -92,27 +92,23 @@ public final class UpdateRegistrarRdapBaseUrlsAction implements Runnable {
|
||||
@Inject
|
||||
UpdateRegistrarRdapBaseUrlsAction() {}
|
||||
|
||||
private String loginAndGetId(HttpRequestFactory requestFactory, String tld) {
|
||||
try {
|
||||
logger.atInfo().log("Logging in to MoSAPI");
|
||||
HttpRequest request =
|
||||
requestFactory.buildGetRequest(new GenericUrl(String.format(LOGIN_URL, tld)));
|
||||
request.getHeaders().setBasicAuthentication(String.format("%s_ry", tld), password);
|
||||
HttpResponse response = request.execute();
|
||||
private String loginAndGetId(HttpRequestFactory requestFactory, String tld) throws IOException {
|
||||
logger.atInfo().log("Logging in to MoSAPI");
|
||||
HttpRequest request =
|
||||
requestFactory.buildGetRequest(new GenericUrl(String.format(LOGIN_URL, tld)));
|
||||
request.getHeaders().setBasicAuthentication(String.format("%s_ry", tld), password);
|
||||
HttpResponse response = request.execute();
|
||||
|
||||
Optional<HttpCookie> idCookie =
|
||||
HttpCookie.parse(response.getHeaders().getFirstHeaderStringValue("Set-Cookie")).stream()
|
||||
.filter(cookie -> cookie.getName().equals(COOKIE_ID))
|
||||
.findAny();
|
||||
checkState(
|
||||
idCookie.isPresent(),
|
||||
"Didn't get the ID cookie from the login response. Code: %s, headers: %s",
|
||||
response.getStatusCode(),
|
||||
response.getHeaders());
|
||||
return idCookie.get().getValue();
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Error logging in to MoSAPI server: " + e.getMessage(), e);
|
||||
}
|
||||
Optional<HttpCookie> idCookie =
|
||||
HttpCookie.parse(response.getHeaders().getFirstHeaderStringValue("Set-Cookie")).stream()
|
||||
.filter(cookie -> cookie.getName().equals(COOKIE_ID))
|
||||
.findAny();
|
||||
checkState(
|
||||
idCookie.isPresent(),
|
||||
"Didn't get the ID cookie from the login response. Code: %s, headers: %s",
|
||||
response.getStatusCode(),
|
||||
response.getHeaders());
|
||||
return idCookie.get().getValue();
|
||||
}
|
||||
|
||||
private void logout(HttpRequestFactory requestFactory, String id, String tld) {
|
||||
@@ -128,9 +124,8 @@ public final class UpdateRegistrarRdapBaseUrlsAction implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
private ImmutableSetMultimap<String, String> getRdapBaseUrlsPerIanaIdWithTld(String tld) {
|
||||
HttpRequestFactory requestFactory = httpTransport.createRequestFactory();
|
||||
String id = loginAndGetId(requestFactory, tld);
|
||||
private ImmutableSetMultimap<String, String> getRdapBaseUrlsPerIanaIdWithTld(
|
||||
String tld, String id, HttpRequestFactory requestFactory) {
|
||||
String content;
|
||||
try {
|
||||
HttpRequest request =
|
||||
@@ -173,11 +168,22 @@ public final class UpdateRegistrarRdapBaseUrlsAction implements Runnable {
|
||||
checkArgument(!tlds.isEmpty(), "There must exist at least one REAL TLD.");
|
||||
Throwable finalThrowable = null;
|
||||
for (String tld : tlds) {
|
||||
HttpRequestFactory requestFactory = httpTransport.createRequestFactory();
|
||||
String id;
|
||||
try {
|
||||
return getRdapBaseUrlsPerIanaIdWithTld(tld);
|
||||
id = loginAndGetId(requestFactory, tld);
|
||||
} catch (Throwable e) {
|
||||
// Login failures are bad but not unexpected for certain TLDs. We shouldn't store those
|
||||
// but rather should only store useful Throwables.
|
||||
logger.atWarning().log("Error logging in to MoSAPI server: " + e.getMessage(), e);
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
return getRdapBaseUrlsPerIanaIdWithTld(tld, id, requestFactory);
|
||||
} catch (Throwable throwable) {
|
||||
logger.atWarning().log(String
|
||||
.format("Error retrieving RDAP urls with TLD %s: %s", tld, throwable.getMessage()));
|
||||
logger.atWarning().log(
|
||||
String.format(
|
||||
"Error retrieving RDAP urls with TLD %s: %s", tld, throwable.getMessage()));
|
||||
finalThrowable = throwable;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,22 +59,19 @@ public class Spec11EmailUtils {
|
||||
private final SendEmailService emailService;
|
||||
private final InternetAddress outgoingEmailAddress;
|
||||
private final InternetAddress alertRecipientAddress;
|
||||
private final InternetAddress spec11ReplyToAddress;
|
||||
private final ImmutableList<String> spec11WebResources;
|
||||
private final String registryName;
|
||||
|
||||
@Inject
|
||||
Spec11EmailUtils(
|
||||
SendEmailService emailService,
|
||||
@Config("gSuiteOutgoingEmailAddress") InternetAddress outgoingEmailAddress,
|
||||
@Config("alertRecipientEmailAddress") InternetAddress alertRecipientAddress,
|
||||
@Config("spec11ReplyToEmailAddress") InternetAddress spec11ReplyToAddress,
|
||||
@Config("spec11OutgoingEmailAddress") InternetAddress spec11OutgoingEmailAddress,
|
||||
@Config("spec11WebResources") ImmutableList<String> spec11WebResources,
|
||||
@Config("registryName") String registryName) {
|
||||
this.emailService = emailService;
|
||||
this.outgoingEmailAddress = outgoingEmailAddress;
|
||||
this.outgoingEmailAddress = spec11OutgoingEmailAddress;
|
||||
this.alertRecipientAddress = alertRecipientAddress;
|
||||
this.spec11ReplyToAddress = spec11ReplyToAddress;
|
||||
this.spec11WebResources = spec11WebResources;
|
||||
this.registryName = registryName;
|
||||
}
|
||||
@@ -149,7 +146,7 @@ public class Spec11EmailUtils {
|
||||
.setContentType(MediaType.HTML_UTF_8)
|
||||
.setFrom(outgoingEmailAddress)
|
||||
.addRecipient(getEmailAddressForRegistrar(registrarThreatMatches.clientId()))
|
||||
.setBcc(spec11ReplyToAddress)
|
||||
.setBcc(outgoingEmailAddress)
|
||||
.build());
|
||||
}
|
||||
|
||||
@@ -172,7 +169,7 @@ public class Spec11EmailUtils {
|
||||
ImmutableMap.of(
|
||||
"date", date.toString(),
|
||||
"registry", registryName,
|
||||
"replyToEmail", spec11ReplyToAddress.getAddress(),
|
||||
"replyToEmail", outgoingEmailAddress.getAddress(),
|
||||
"threats", threatMatchMap,
|
||||
"resources", spec11WebResources);
|
||||
renderer.setData(data);
|
||||
|
||||
@@ -52,7 +52,7 @@ final class CreateAnchorTenantCommand extends MutatingEppToolCommand {
|
||||
|
||||
@Parameter(
|
||||
names = {"--contact"},
|
||||
description = "Contact ID for the request. This will be used for registrant, admin contact,"
|
||||
description = "Contact ID for the request. This will be used for registrant, admin contact, "
|
||||
+ "and tech contact.",
|
||||
required = true)
|
||||
private String contact;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<!doctype html>
|
||||
<meta http-equiv="refresh" content="0;URL=/registrar">
|
||||
<title>Nomulus</title>
|
||||
<body>
|
||||
<body lang="en-US">
|
||||
If this page doesn't change automatically, please go
|
||||
to <a href="/registrar">https://www.registry.google/registrar</a>
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
{@param logoutUrl: string}
|
||||
{@param logoFilename: string}
|
||||
{@param productName: string}
|
||||
<div id="kd-googlebar" role="banner">
|
||||
<div id="kd-googlebar" role="banner" lang="en-US">
|
||||
<a class="{css('logo')}" href="/registrar">
|
||||
<img src="/assets/images/{$logoFilename}" alt="{$productName}">
|
||||
</a>
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
{param analyticsConfig: $analyticsConfig /}
|
||||
{/call}
|
||||
{call registry.soy.console.googlebar data="all" /}
|
||||
<div id="reg-app">
|
||||
<div id="reg-app" lang="en-US">
|
||||
<div id="reg-appbar" class="{css('kd-appbar')}">
|
||||
<div class="{css('kd-description')}">
|
||||
Accessing <span class="{css('kd-value')}">{$clientId}</span> as{sp}
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.google.api.client.testing.http.MockLowLevelHttpRequest;
|
||||
import com.google.api.client.testing.http.MockLowLevelHttpResponse;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.model.registrar.RegistrarAddress;
|
||||
import google.registry.model.registry.Registry;
|
||||
@@ -276,6 +277,44 @@ public final class UpdateRegistrarRdapBaseUrlsActionTest extends ShardableTestCa
|
||||
.isEqualTo("Error contacting MosAPI server. Tried TLDs [secondtld, tld]");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailureCause_ignoresLoginFailure() {
|
||||
// Login failures aren't particularly interesting so we should log them, but the final
|
||||
// throwable should be some other failure if one existed
|
||||
createTld("secondtld");
|
||||
httpTransport = new TestHttpTransport();
|
||||
action.httpTransport = httpTransport;
|
||||
|
||||
MockLowLevelHttpResponse loginResponse = new MockLowLevelHttpResponse();
|
||||
loginResponse.addHeader(
|
||||
"Set-Cookie",
|
||||
"id=myAuthenticationId; "
|
||||
+ "Expires=Tue, 11-Jun-2019 16:34:21 GMT; Path=/mosapi/v1/app; Secure; HttpOnly");
|
||||
|
||||
MockLowLevelHttpResponse badListResponse = new MockLowLevelHttpResponse();
|
||||
String badListReply = JSON_LIST_REPLY.substring(50);
|
||||
badListResponse.setContent(badListReply);
|
||||
|
||||
MockLowLevelHttpResponse logoutResponse = new MockLowLevelHttpResponse();
|
||||
logoutResponse.addHeader(
|
||||
"Set-Cookie",
|
||||
"id=id; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/mosapi/v1/app; Secure; HttpOnly");
|
||||
|
||||
MockLowLevelHttpResponse badLoginResponse = new MockLowLevelHttpResponse();
|
||||
badLoginResponse.addHeader(
|
||||
"Set-Cookie",
|
||||
"Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/mosapi/v1/app; Secure; HttpOnly");
|
||||
|
||||
httpTransport.addNextResponse(loginResponse);
|
||||
httpTransport.addNextResponse(badListResponse);
|
||||
httpTransport.addNextResponse(logoutResponse);
|
||||
httpTransport.addNextResponse(badLoginResponse);
|
||||
|
||||
assertThat(assertThrows(RuntimeException.class, action::run))
|
||||
.hasCauseThat()
|
||||
.isInstanceOf(JsonSyntaxException.class);
|
||||
}
|
||||
|
||||
private static void addValidResponses(TestHttpTransport httpTransport) {
|
||||
MockLowLevelHttpResponse loginResponse = new MockLowLevelHttpResponse();
|
||||
loginResponse.addHeader(
|
||||
|
||||
@@ -87,7 +87,7 @@ public class Spec11EmailUtilsTest {
|
||||
+ "update your abuse contact using your registrar portal account.</p>"
|
||||
+ ""
|
||||
+ "<p>If you have any questions regarding this notice, please contact "
|
||||
+ "my-reply-to@test.com.</p>";
|
||||
+ "abuse@test.com.</p>";
|
||||
private static final String MONTHLY_EMAIL_FORMAT =
|
||||
"Dear registrar partner,"
|
||||
+ ""
|
||||
@@ -117,7 +117,7 @@ public class Spec11EmailUtilsTest {
|
||||
+ "our monthly reporting.</p>"
|
||||
+ ""
|
||||
+ "<p>If you have any questions regarding this notice, please contact "
|
||||
+ "my-reply-to@test.com.</p>";
|
||||
+ "abuse@test.com.</p>";
|
||||
|
||||
@Rule public final AppEngineRule appEngine = AppEngineRule.builder().withDatastore().build();
|
||||
|
||||
@@ -139,9 +139,8 @@ public class Spec11EmailUtilsTest {
|
||||
emailUtils =
|
||||
new Spec11EmailUtils(
|
||||
emailService,
|
||||
new InternetAddress("my-sender@test.com"),
|
||||
new InternetAddress("my-receiver@test.com"),
|
||||
new InternetAddress("my-reply-to@test.com"),
|
||||
new InternetAddress("abuse@test.com"),
|
||||
FAKE_RESOURCES,
|
||||
"Super Cool Registry");
|
||||
|
||||
@@ -164,17 +163,17 @@ public class Spec11EmailUtilsTest {
|
||||
List<EmailMessage> capturedContents = contentCaptor.getAllValues();
|
||||
validateMessage(
|
||||
capturedContents.get(0),
|
||||
"my-sender@test.com",
|
||||
"abuse@test.com",
|
||||
"the.registrar@example.com",
|
||||
Optional.of("my-reply-to@test.com"),
|
||||
Optional.of("abuse@test.com"),
|
||||
"Super Cool Registry Monthly Threat Detector [2018-07-15]",
|
||||
String.format(MONTHLY_EMAIL_FORMAT, "<tr><td>a.com</td><td>MALWARE</td></tr>"),
|
||||
Optional.of(MediaType.HTML_UTF_8));
|
||||
validateMessage(
|
||||
capturedContents.get(1),
|
||||
"my-sender@test.com",
|
||||
"abuse@test.com",
|
||||
"new.registrar@example.com",
|
||||
Optional.of("my-reply-to@test.com"),
|
||||
Optional.of("abuse@test.com"),
|
||||
"Super Cool Registry Monthly Threat Detector [2018-07-15]",
|
||||
String.format(
|
||||
MONTHLY_EMAIL_FORMAT,
|
||||
@@ -182,7 +181,7 @@ public class Spec11EmailUtilsTest {
|
||||
Optional.of(MediaType.HTML_UTF_8));
|
||||
validateMessage(
|
||||
capturedContents.get(2),
|
||||
"my-sender@test.com",
|
||||
"abuse@test.com",
|
||||
"my-receiver@test.com",
|
||||
Optional.empty(),
|
||||
"Spec11 Pipeline Success 2018-07-15",
|
||||
@@ -202,17 +201,17 @@ public class Spec11EmailUtilsTest {
|
||||
List<EmailMessage> capturedMessages = contentCaptor.getAllValues();
|
||||
validateMessage(
|
||||
capturedMessages.get(0),
|
||||
"my-sender@test.com",
|
||||
"abuse@test.com",
|
||||
"the.registrar@example.com",
|
||||
Optional.of("my-reply-to@test.com"),
|
||||
Optional.of("abuse@test.com"),
|
||||
"Super Cool Registry Daily Threat Detector [2018-07-15]",
|
||||
String.format(DAILY_EMAIL_FORMAT, "<tr><td>a.com</td><td>MALWARE</td></tr>"),
|
||||
Optional.of(MediaType.HTML_UTF_8));
|
||||
validateMessage(
|
||||
capturedMessages.get(1),
|
||||
"my-sender@test.com",
|
||||
"abuse@test.com",
|
||||
"new.registrar@example.com",
|
||||
Optional.of("my-reply-to@test.com"),
|
||||
Optional.of("abuse@test.com"),
|
||||
"Super Cool Registry Daily Threat Detector [2018-07-15]",
|
||||
String.format(
|
||||
DAILY_EMAIL_FORMAT,
|
||||
@@ -220,7 +219,7 @@ public class Spec11EmailUtilsTest {
|
||||
Optional.of(MediaType.HTML_UTF_8));
|
||||
validateMessage(
|
||||
capturedMessages.get(2),
|
||||
"my-sender@test.com",
|
||||
"abuse@test.com",
|
||||
"my-receiver@test.com",
|
||||
Optional.empty(),
|
||||
"Spec11 Pipeline Success 2018-07-15",
|
||||
@@ -247,15 +246,15 @@ public class Spec11EmailUtilsTest {
|
||||
List<EmailMessage> capturedContents = contentCaptor.getAllValues();
|
||||
validateMessage(
|
||||
capturedContents.get(0),
|
||||
"my-sender@test.com",
|
||||
"abuse@test.com",
|
||||
"new.registrar@example.com",
|
||||
Optional.of("my-reply-to@test.com"),
|
||||
Optional.of("abuse@test.com"),
|
||||
"Super Cool Registry Monthly Threat Detector [2018-07-15]",
|
||||
String.format(MONTHLY_EMAIL_FORMAT, "<tr><td>c.com</td><td>MALWARE</td></tr>"),
|
||||
Optional.of(MediaType.HTML_UTF_8));
|
||||
validateMessage(
|
||||
capturedContents.get(1),
|
||||
"my-sender@test.com",
|
||||
"abuse@test.com",
|
||||
"my-receiver@test.com",
|
||||
Optional.empty(),
|
||||
"Spec11 Pipeline Success 2018-07-15",
|
||||
@@ -292,17 +291,17 @@ public class Spec11EmailUtilsTest {
|
||||
List<EmailMessage> capturedMessages = contentCaptor.getAllValues();
|
||||
validateMessage(
|
||||
capturedMessages.get(0),
|
||||
"my-sender@test.com",
|
||||
"abuse@test.com",
|
||||
"the.registrar@example.com",
|
||||
Optional.of("my-reply-to@test.com"),
|
||||
Optional.of("abuse@test.com"),
|
||||
"Super Cool Registry Monthly Threat Detector [2018-07-15]",
|
||||
String.format(MONTHLY_EMAIL_FORMAT, "<tr><td>a.com</td><td>MALWARE</td></tr>"),
|
||||
Optional.of(MediaType.HTML_UTF_8));
|
||||
validateMessage(
|
||||
capturedMessages.get(1),
|
||||
"my-sender@test.com",
|
||||
"abuse@test.com",
|
||||
"new.registrar@example.com",
|
||||
Optional.of("my-reply-to@test.com"),
|
||||
Optional.of("abuse@test.com"),
|
||||
"Super Cool Registry Monthly Threat Detector [2018-07-15]",
|
||||
String.format(
|
||||
MONTHLY_EMAIL_FORMAT,
|
||||
@@ -310,7 +309,7 @@ public class Spec11EmailUtilsTest {
|
||||
Optional.of(MediaType.HTML_UTF_8));
|
||||
validateMessage(
|
||||
capturedMessages.get(2),
|
||||
"my-sender@test.com",
|
||||
"abuse@test.com",
|
||||
"my-receiver@test.com",
|
||||
Optional.empty(),
|
||||
"Spec11 Emailing Failure 2018-07-15",
|
||||
@@ -324,7 +323,7 @@ public class Spec11EmailUtilsTest {
|
||||
verify(emailService).sendEmail(contentCaptor.capture());
|
||||
validateMessage(
|
||||
contentCaptor.getValue(),
|
||||
"my-sender@test.com",
|
||||
"abuse@test.com",
|
||||
"my-receiver@test.com",
|
||||
Optional.empty(),
|
||||
"Spec11 Pipeline Alert: 2018-07",
|
||||
|
||||
+1
-1
@@ -4,4 +4,4 @@ uploaderDestination=
|
||||
uploaderCredentialsFile=
|
||||
uploaderMultithreadedUpload=
|
||||
flowDocsFile=
|
||||
disableDependencyLocking=false
|
||||
enableDependencyLocking=true
|
||||
|
||||
@@ -25,8 +25,6 @@ import com.google.api.services.cloudkms.v1.model.DecryptRequest;
|
||||
import com.google.api.services.storage.Storage;
|
||||
import com.google.auth.oauth2.AccessToken;
|
||||
import com.google.auth.oauth2.GoogleCredentials;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.flogger.LoggerConfig;
|
||||
import com.google.monitoring.metrics.MetricReporter;
|
||||
import dagger.Component;
|
||||
@@ -185,12 +183,6 @@ public class ProxyModule {
|
||||
return Optional.ofNullable(httpsWhoisPort).orElse(config.webWhois.httpsPort);
|
||||
}
|
||||
|
||||
@Provides
|
||||
ImmutableMap<Integer, FrontendProtocol> providePortToProtocolMap(
|
||||
Set<FrontendProtocol> protocolSet) {
|
||||
return Maps.uniqueIndex(protocolSet, Protocol::port);
|
||||
}
|
||||
|
||||
@Provides
|
||||
Environment provideEnvironment() {
|
||||
return env;
|
||||
@@ -359,7 +351,7 @@ public class ProxyModule {
|
||||
})
|
||||
interface ProxyComponent {
|
||||
|
||||
ImmutableMap<Integer, FrontendProtocol> portToProtocolMap();
|
||||
Set<FrontendProtocol> protocols();
|
||||
|
||||
MetricReporter metricReporter();
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import static google.registry.proxy.handler.RelayHandler.RELAY_CHANNEL_KEY;
|
||||
import static google.registry.proxy.handler.RelayHandler.writeToRelayChannel;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.google.monitoring.metrics.MetricReporter;
|
||||
import google.registry.proxy.Protocol.BackendProtocol;
|
||||
@@ -51,28 +51,27 @@ import java.util.concurrent.TimeoutException;
|
||||
import javax.inject.Provider;
|
||||
|
||||
/**
|
||||
* A multi-protocol proxy server that listens on port(s) specified in {@link
|
||||
* ProxyModule.ProxyComponent#portToProtocolMap()} }.
|
||||
* A multi-protocol proxy server that listens for protocols in {@link
|
||||
* ProxyModule.ProxyComponent#protocols()} }.
|
||||
*/
|
||||
public class ProxyServer implements Runnable {
|
||||
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
|
||||
/** Maximum length of the queue of incoming connections. */
|
||||
private static final int MAX_SOCKET_BACKLOG = 128;
|
||||
|
||||
private final ImmutableMap<Integer, FrontendProtocol> portToProtocolMap;
|
||||
private final ImmutableSet<FrontendProtocol> protocols;
|
||||
private final HashMap<Integer, Channel> portToChannelMap = new HashMap<>();
|
||||
private final EventLoopGroup eventGroup = new NioEventLoopGroup();
|
||||
|
||||
ProxyServer(ProxyComponent proxyComponent) {
|
||||
this.portToProtocolMap = proxyComponent.portToProtocolMap();
|
||||
this.protocols = ImmutableSet.copyOf(proxyComponent.protocols());
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link ChannelInitializer} for connections from a client of a certain protocol.
|
||||
*
|
||||
* <p>The {@link #initChannel} method does the following:
|
||||
* <p>The {@link #initChannel(NioSocketChannel)} method does the following:
|
||||
*
|
||||
* <ol>
|
||||
* <li>Determine the {@link FrontendProtocol} of the inbound {@link Channel} from its parent
|
||||
@@ -263,8 +262,9 @@ public class ProxyServer implements Runnable {
|
||||
.childOption(ChannelOption.AUTO_READ, false);
|
||||
|
||||
// Bind to each port specified in portToHandlersMap.
|
||||
portToProtocolMap.forEach(
|
||||
(port, protocol) -> {
|
||||
protocols.forEach(
|
||||
protocol -> {
|
||||
int port = protocol.port();
|
||||
try {
|
||||
// Wait for binding to be established for each listening port.
|
||||
ChannelFuture serverChannelFuture = serverBootstrap.bind(port).sync();
|
||||
|
||||
Reference in New Issue
Block a user