mirror of
https://github.com/google/nomulus
synced 2026-07-19 14:32:44 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bf66b374c6 | |||
| 666cee1d9f | |||
| d4a70c29a8 | |||
| 7b8d07954b | |||
| 34bea69a48 | |||
| 363800bd86 | |||
| dee132d04b |
@@ -121,9 +121,5 @@ core/**/registrar_dbg*.js
|
||||
core/**/registrar_bin*.css
|
||||
core/**/registrar_dbg*.css
|
||||
|
||||
# Appengine generated files
|
||||
core/WEB-INF/appengine-generated/*.bin
|
||||
core/WEB-INF/appengine-generated/*.xml
|
||||
|
||||
# jEnv
|
||||
.java-version
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
// Copyright 2019 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.
|
||||
|
||||
apply plugin: 'war'
|
||||
|
||||
def environment = rootProject.environment
|
||||
def gcpProject = rootProject.gcpProject
|
||||
|
||||
// Set this directory before applying the appengine plugin so that the
|
||||
// plugin will recognize this as an app-engine standard app (and also
|
||||
// obtains the appengine-web.xml from the correct location)
|
||||
project.convention.plugins['war'].webAppDirName =
|
||||
"../../core/src/main/java/google/registry/env/${environment}/${project.name}"
|
||||
|
||||
apply plugin: 'com.google.cloud.tools.appengine'
|
||||
|
||||
def coreResourcesDir = "${rootDir}/core/build/resources/main"
|
||||
def coreLibsDir = "${rootDir}/core/build/libs"
|
||||
|
||||
// Get the web.xml file for the service.
|
||||
war {
|
||||
webInf {
|
||||
from "../../core/src/main/java/google/registry/env/common/${project.name}/WEB-INF"
|
||||
}
|
||||
}
|
||||
|
||||
war {
|
||||
from("${coreResourcesDir}/google/registry/ui/html") {
|
||||
include "*.html"
|
||||
}
|
||||
from("${coreLibsDir}") {
|
||||
include "core.jar"
|
||||
into("WEB-INF/lib")
|
||||
}
|
||||
}
|
||||
|
||||
if (project.path == ":services:default") {
|
||||
war {
|
||||
from("${coreResourcesDir}/google/registry/ui/html") {
|
||||
include "*.html"
|
||||
into("registrar")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
appengine {
|
||||
deploy {
|
||||
// appengineDeployAll task requires the version to be set. So,
|
||||
// this config lets gcloud select a version name when deploying
|
||||
// to alpha or sandbox from our workstation.
|
||||
if (!rootProject.prodOrSandboxEnv) {
|
||||
version = 'GCLOUD_CONFIG'
|
||||
}
|
||||
|
||||
// Don't set gcpProject directly, it gets overriden in ./build.gradle.
|
||||
// Do -P environment={crash,alpha} instead. For sandbox/production,
|
||||
// use Spinnaker.
|
||||
projectId = gcpProject
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(path: ':core', configuration: 'deploy_jar')
|
||||
}
|
||||
|
||||
// The tools.jar file gets pulled in from the java environment and for some
|
||||
// reason gets exploded "readonly", causing subsequent builds to fail when
|
||||
// they can't overwrite it. The hack below makes the file writable after
|
||||
// we're done exploding it.
|
||||
//
|
||||
// Fun fact: We only use this jar for documentation generation and as such we
|
||||
// don't need it in our warfile, as it is not used by the application at
|
||||
// runtime. But it's not clear how to exclude it, as we seem to be
|
||||
// constructing the jar from the entire WEB-INF directory and per-file
|
||||
// exclude rules don't seem to work on it. Better solutions are welcome :-)
|
||||
explodeWar.doLast {
|
||||
file("${it.explodedAppDirectory}/WEB-INF/lib/tools.jar").setWritable(true)
|
||||
}
|
||||
|
||||
appengineDeployAll.mustRunAfter ':console-webapp:deploy'
|
||||
appengineDeployAll.finalizedBy ':deployCloudSchedulerAndQueue'
|
||||
|
||||
rootProject.stage.dependsOn appengineStage
|
||||
tasks['war'].dependsOn ':core:processResources'
|
||||
tasks['war'].dependsOn ':core:jar'
|
||||
|
||||
// Impose verification for all of the deployment tasks. We haven't found a
|
||||
// better way to do this other than to apply to each of them independently.
|
||||
// If a new task gets added, it will still fail if "environment" is not defined
|
||||
// because gcpProject is null. We just won't get as friendly an error message.
|
||||
appengineDeployAll.configure rootProject.verifyDeploymentConfig
|
||||
appengineDeploy.configure rootProject.verifyDeploymentConfig
|
||||
appengineDeployCron.configure rootProject.verifyDeploymentConfig
|
||||
appengineDeployDispatch.configure rootProject.verifyDeploymentConfig
|
||||
appengineDeployDos.configure rootProject.verifyDeploymentConfig
|
||||
appengineDeployIndex.configure rootProject.verifyDeploymentConfig
|
||||
appengineDeployQueue.configure rootProject.verifyDeploymentConfig
|
||||
@@ -331,9 +331,6 @@ subprojects {
|
||||
|
||||
// Set up all of the deployment projects.
|
||||
if (services.contains(project.path)) {
|
||||
|
||||
apply from: "${rootDir.path}/appengine_war.gradle"
|
||||
|
||||
// Return early, do not apply the settings below.
|
||||
return
|
||||
}
|
||||
@@ -380,17 +377,6 @@ subprojects {
|
||||
}
|
||||
}
|
||||
|
||||
// Force SDK download and deployment to be sequential, otherwise parallel tasks
|
||||
// will fail. For SDK download, they will try to write to the same location to
|
||||
// upgrade gcloud. For deployment, they will try to deploy different services to
|
||||
// the same project at the same time.
|
||||
for (int i = 1; i < services.size(); i++) {
|
||||
project("${services[i]}").downloadCloudSdk
|
||||
.dependsOn(project("${services[i - 1]}").downloadCloudSdk)
|
||||
project("${services[i]}").appengineDeployAll
|
||||
.dependsOn(project("${services[i - 1]}").appengineDeployAll)
|
||||
}
|
||||
|
||||
// If "-P verboseTestOutput=true" is passed in, configure all subprojects to dump all of their
|
||||
// output and final test status (pass/fail, errors) for each test class.
|
||||
//
|
||||
|
||||
@@ -47,9 +47,9 @@ export interface Contact {
|
||||
registrarId?: string;
|
||||
faxNumber?: string;
|
||||
types: Array<contactType>;
|
||||
visibleInWhoisAsAdmin?: boolean;
|
||||
visibleInWhoisAsTech?: boolean;
|
||||
visibleInDomainWhoisAsAbuse?: boolean;
|
||||
visibleInRdapAsAdmin?: boolean;
|
||||
visibleInRdapAsTech?: boolean;
|
||||
visibleInDomainRdapAsAbuse?: boolean;
|
||||
}
|
||||
|
||||
export interface ViewReadyContact extends Contact {
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
<h1>RDAP Preferences</h1>
|
||||
<div>
|
||||
<mat-checkbox
|
||||
[(ngModel)]="contactService.contactInEdit.visibleInWhoisAsAdmin"
|
||||
[(ngModel)]="contactService.contactInEdit.visibleInRdapAsAdmin"
|
||||
[ngModelOptions]="{ standalone: true }"
|
||||
>Show in Registrar RDAP record as admin contact</mat-checkbox
|
||||
>
|
||||
@@ -119,7 +119,7 @@
|
||||
|
||||
<div>
|
||||
<mat-checkbox
|
||||
[(ngModel)]="contactService.contactInEdit.visibleInWhoisAsTech"
|
||||
[(ngModel)]="contactService.contactInEdit.visibleInRdapAsTech"
|
||||
[ngModelOptions]="{ standalone: true }"
|
||||
>Show in Registrar RDAP record as technical contact</mat-checkbox
|
||||
>
|
||||
@@ -127,7 +127,7 @@
|
||||
|
||||
<div>
|
||||
<mat-checkbox
|
||||
[(ngModel)]="contactService.contactInEdit.visibleInDomainWhoisAsAbuse"
|
||||
[(ngModel)]="contactService.contactInEdit.visibleInDomainRdapAsAbuse"
|
||||
[ngModelOptions]="{ standalone: true }"
|
||||
>Show Phone and Email in Domain RDAP Record as registrar abuse contact
|
||||
(per CL&D requirements)</mat-checkbox
|
||||
@@ -189,24 +189,24 @@
|
||||
<mat-list-item role="listitem">
|
||||
<h2>RDAP Preferences</h2>
|
||||
</mat-list-item>
|
||||
@if(contactService.contactInEdit.visibleInWhoisAsAdmin) {
|
||||
@if(contactService.contactInEdit.visibleInRdapAsAdmin) {
|
||||
<mat-divider></mat-divider>
|
||||
<mat-list-item role="listitem">
|
||||
<span class="console-app__list-value"
|
||||
>Show in Registrar RDAP record as admin contact</span
|
||||
>
|
||||
</mat-list-item>
|
||||
} @if(contactService.contactInEdit.visibleInWhoisAsTech) {
|
||||
} @if(contactService.contactInEdit.visibleInRdapAsTech) {
|
||||
<mat-divider></mat-divider>
|
||||
<mat-list-item
|
||||
role="listitem"
|
||||
*ngIf="contactService.contactInEdit.visibleInWhoisAsTech"
|
||||
*ngIf="contactService.contactInEdit.visibleInRdapAsTech"
|
||||
>
|
||||
<span class="console-app__list-value"
|
||||
>Show in Registrar RDAP record as technical contact</span
|
||||
>
|
||||
</mat-list-item>
|
||||
} @if(contactService.contactInEdit.visibleInDomainWhoisAsAbuse) {
|
||||
} @if(contactService.contactInEdit.visibleInDomainRdapAsAbuse) {
|
||||
<mat-divider></mat-divider>
|
||||
<mat-list-item role="listitem">
|
||||
<span class="console-app__list-value"
|
||||
|
||||
@@ -1556,12 +1556,7 @@ public final class RegistryConfig {
|
||||
return CONFIG_SETTINGS.get().gSuite.outgoingEmailDisplayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns default WHOIS server to use when {@code Registrar#getWhoisServer()} is {@code null}.
|
||||
*
|
||||
* @see "google.registry.whois.DomainWhoisResponse"
|
||||
* @see "google.registry.whois.RegistrarWhoisResponse"
|
||||
*/
|
||||
/** Returns default WHOIS server to use when {@code Registrar#getWhoisServer()} is null. */
|
||||
public static String getDefaultRegistrarWhoisServer() {
|
||||
return CONFIG_SETTINGS.get().registryPolicy.defaultRegistrarWhoisServer;
|
||||
}
|
||||
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>backend</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>100</max-instances>
|
||||
<idle-timeout>10m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="alpha"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1m"/>
|
||||
</static-files>
|
||||
</appengine-web-app>
|
||||
@@ -1,34 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>bsa</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>100</max-instances>
|
||||
<idle-timeout>10m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="alpha"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<!-- Enable external traffic to go through VPC, required for static ip -->
|
||||
<vpc-access-connector>
|
||||
<name>projects/domain-registry-alpha/locations/us-central1/connectors/appengine-connector</name>
|
||||
<egress-setting>all-traffic</egress-setting>
|
||||
</vpc-access-connector>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1m"/>
|
||||
</static-files>
|
||||
</appengine-web-app>
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>default</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>8</max-instances>
|
||||
<idle-timeout>30m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="alpha"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1m"/>
|
||||
<include path="/registrar/*.html" expiration="1m"/>
|
||||
|
||||
</static-files>
|
||||
</appengine-web-app>
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>pubapi</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>8</max-instances>
|
||||
<idle-timeout>10m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="alpha"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1m"/>
|
||||
<include path="/assets/js/**" expiration="1m"/>
|
||||
<include path="/assets/css/**" expiration="1m"/>
|
||||
<include path="/assets/images/**" expiration="1m"/>
|
||||
</static-files>
|
||||
</appengine-web-app>
|
||||
@@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>tools</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>5</max-instances>
|
||||
<idle-timeout>5m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="alpha"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1m"/>
|
||||
<include path="/assets/js/**" expiration="1m"/>
|
||||
<include path="/assets/css/**" expiration="1m"/>
|
||||
<include path="/assets/images/**" expiration="1m"/>
|
||||
</static-files>
|
||||
</appengine-web-app>
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<appengine-application xmlns="http://appengine.google.com/ns/1.0">
|
||||
<application>domain-registry</application>
|
||||
</appengine-application>
|
||||
@@ -1,46 +0,0 @@
|
||||
<?xml version="1.0"
|
||||
encoding="UTF-8"?>
|
||||
|
||||
<application
|
||||
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
|
||||
http://java.sun.com/xml/ns/javaee/application_5.xsd"
|
||||
version="5">
|
||||
|
||||
<description>Google Registry</description>
|
||||
<display-name>Google Registry</display-name>
|
||||
|
||||
<!-- Modules -->
|
||||
<!-- The default module should be listed first -->
|
||||
<module>
|
||||
<web>
|
||||
<web-uri>default</web-uri>
|
||||
<context-root>default</context-root>
|
||||
</web>
|
||||
</module>
|
||||
<module>
|
||||
<web>
|
||||
<web-uri>pubapi</web-uri>
|
||||
<context-root>pubapi</context-root>
|
||||
</web>
|
||||
</module>
|
||||
<module>
|
||||
<web>
|
||||
<web-uri>backend</web-uri>
|
||||
<context-root>backend</context-root>
|
||||
</web>
|
||||
</module>
|
||||
<module>
|
||||
<web>
|
||||
<web-uri>bsa</web-uri>
|
||||
<context-root>bsa</context-root>
|
||||
</web>
|
||||
</module>
|
||||
<module>
|
||||
<web>
|
||||
<web-uri>tools</web-uri>
|
||||
<context-root>tools</context-root>
|
||||
</web>
|
||||
</module>
|
||||
</application>
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
# A default java.util.logging configuration.
|
||||
# (All App Engine logging is through java.util.logging by default).
|
||||
#
|
||||
# To use this configuration, copy it into your application's WEB-INF
|
||||
# folder and add the following to your appengine-web.xml:
|
||||
#
|
||||
# <system-properties>
|
||||
# <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
|
||||
# </system-properties>
|
||||
#
|
||||
|
||||
# Set the default logging level for all loggers to INFO.
|
||||
.level = INFO
|
||||
|
||||
# Turn off logging in Hibernate classes for misleading ERROR-level logs
|
||||
org.hibernate.orm.jdbc.batch.level=OFF
|
||||
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.level=OFF
|
||||
@@ -1,333 +0,0 @@
|
||||
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
|
||||
version="6.0">
|
||||
<!-- Servlets -->
|
||||
|
||||
<!-- Servlet for injected backends actions -->
|
||||
<servlet>
|
||||
<display-name>BackendServlet</display-name>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<servlet-class>google.registry.module.backend.BackendServlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<!-- RDE -->
|
||||
|
||||
<!--
|
||||
Responsible for scanning the database to create a full deposit for a single TLD
|
||||
and streaming it to cloud storage. Requests are sent here by App Engine after
|
||||
`RdeCreateCronServlet` enqueues a task specifying a URL that points to this servlet.
|
||||
-->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/rdeStaging</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!--
|
||||
Once `rdeCreateFullCron` finishes writing a deposit file to cloud storage, it'll
|
||||
launch this task with the cloud filename so it can be uploaded to Iron Mountain
|
||||
via SFTP. The file is deleted once the upload completes. This should be run via
|
||||
`rde-upload-backend`.
|
||||
-->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/rdeUpload</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Sends an XML RDE report to ICANN's HTTP server after rdeUploadTask finishes. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/rdeReport</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!--
|
||||
Bulk Registration Data Access. This task creates a thin escrow deposit
|
||||
and saves it to cloud storage, where a separate script owned by the SREs
|
||||
uploads it to ICANN.
|
||||
-->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/brdaCopy</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Billing -->
|
||||
|
||||
<!--
|
||||
Generates the invoice CSV for the month, which we send to billing to charge
|
||||
registrars for their registrations.
|
||||
-->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/generateInvoices</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!--
|
||||
Emails the month's invoice CSV to the internal billing team, and publishes
|
||||
the detail reports to the individual registrars' drive accounts.
|
||||
-->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/publishInvoices</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!--
|
||||
Copies invoice detail reports from GCS to the associated registrar's Drive folder.
|
||||
-->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/copyDetailReports</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- ICANN Monthly Reporting -->
|
||||
|
||||
<!--
|
||||
Monthly ICANN transaction and activity reports. This task generates report
|
||||
files (in CSV format) and stores them in GCS under
|
||||
gs://domain-registry-reporting/icann/monthly/YYYY-MM
|
||||
by default.
|
||||
-->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/icannReportingStaging</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!--
|
||||
Monthly ICANN transaction and activity reports. This task uploads the generated
|
||||
report files (in CSV format) via an HTTP PUT to ICANN's endpoint.
|
||||
-->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/icannReportingUpload</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!--
|
||||
Generates the Spec11 report for the month, storing it on GCS.
|
||||
-->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/generateSpec11</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!--
|
||||
Publishes the Spec11 report for the month, emailing registrars about their
|
||||
registrations which were flagged by the SafeBrowsing API.
|
||||
-->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/publishSpec11</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Trademark Clearinghouse -->
|
||||
|
||||
<!-- Downloads TMCH DNL data from MarksDB. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/tmchDnl</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Downloads TMCH SMDRL data from MarksDB. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/tmchSmdrl</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Downloads TMCH CRL data from MarksDB. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/tmchCrl</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Reads the LORDN queues and uploads CSV data for sunrise and claims marks to MarksDB. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/nordnUpload</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Verifies upload of LORDN data to MarksDB. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/nordnVerify</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Reads the DNS refresh requests and kick off the appropriate tasks to update zone. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/readDnsRefreshRequests</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Publishes DNS updates. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/publishDnsUpdates</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Manually refreshes DNS information. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/dnsRefresh</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Fans out a cron task over an adjustable range of TLDs. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/cron/fanout</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Syncs registrars to the registrar spreadsheet. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/syncRegistrarsSheet</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Exports TLD premium terms. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/exportPremiumTerms</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Exports TLD reserved terms. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/exportReservedTerms</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Syncs RegistrarContact changes to Google Groups. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/syncGroupMembers</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/exportDomainLists</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Action to delete all prober data. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/deleteProberData</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Action to delete load test data. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/deleteLoadTestData</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Dataflow pipeline to re-save all EPP resources. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/resaveAllEppResourcesPipeline</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Reread all Registrar RDAP Base Urls from the ICANN endpoint. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/updateRegistrarRdapBaseUrls</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Action to re-save a given entity. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/resaveEntity</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Enqueues DNS update tasks following a host rename. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/refreshDnsOnHostRename</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Action to expand BillingRecurrences into BillingEvents. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/expandBillingRecurrences</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Background action to delete domains past end of autorenewal. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/deleteExpiredDomains</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Background action to send notification emails to registrars with expiring certificate. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/sendExpiringCertificateNotificationEmail</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Action to automatically re-lock a domain after unlocking it -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/relockDomain</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Background action to wipe out PII fields of ContactHistory entities that
|
||||
have been in the database for a certain period of time. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/wipeOutContactHistoryPii</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Action to wipeout Cloud SQL data -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/wipeOutCloudSql</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Action to execute canned scripts -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/executeCannedScript</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Security config -->
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>Internal</web-resource-name>
|
||||
<description>
|
||||
Admin-only internal section. Requests for paths covered by the URL patterns below will be
|
||||
checked for a logged-in user account that's allowed to access the AppEngine admin console
|
||||
(NOTE: this includes Editor/Viewer permissions in addition to Owner and the new IAM
|
||||
App Engine Admin role. See https://cloud.google.com/appengine/docs/java/access-control
|
||||
specifically the "Access handlers that have a login:admin restriction" line.)
|
||||
|
||||
TODO(b/28219927): lift some of these restrictions so that we can allow OAuth authentication
|
||||
for endpoints that need to be accessed by open-source automated processes.
|
||||
</description>
|
||||
|
||||
<!-- Internal AppEngine endpoints. The '_ah' is short for app hosting. -->
|
||||
<url-pattern>/_ah/*</url-pattern>
|
||||
|
||||
<!-- Registrar console (should not be available on non-default module). -->
|
||||
<url-pattern>/registrar*</url-pattern>
|
||||
|
||||
<!-- Verbatim JavaScript sources (only visible to admins for debugging). -->
|
||||
<url-pattern>/assets/sources/*</url-pattern>
|
||||
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>admin</role-name>
|
||||
</auth-constraint>
|
||||
|
||||
<!-- Repeated here since catch-all rule below is not inherited. -->
|
||||
<user-data-constraint>
|
||||
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
||||
</user-data-constraint>
|
||||
</security-constraint>
|
||||
|
||||
<!-- Require TLS on all requests. -->
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>Secure</web-resource-name>
|
||||
<description>
|
||||
Require encryption for all paths. http URLs will be redirected to https.
|
||||
</description>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</web-resource-collection>
|
||||
<user-data-constraint>
|
||||
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
||||
</user-data-constraint>
|
||||
</security-constraint>
|
||||
</web-app>
|
||||
@@ -1,17 +0,0 @@
|
||||
# A default java.util.logging configuration.
|
||||
# (All App Engine logging is through java.util.logging by default).
|
||||
#
|
||||
# To use this configuration, copy it into your application's WEB-INF
|
||||
# folder and add the following to your appengine-web.xml:
|
||||
#
|
||||
# <system-properties>
|
||||
# <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
|
||||
# </system-properties>
|
||||
#
|
||||
|
||||
# Set the default logging level for all loggers to INFO.
|
||||
.level = INFO
|
||||
|
||||
# Turn off logging in Hibernate classes for misleading ERROR-level logs
|
||||
org.hibernate.orm.jdbc.batch.level=OFF
|
||||
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.level=OFF
|
||||
@@ -1,87 +0,0 @@
|
||||
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
|
||||
version="6.0">
|
||||
<!-- Servlets -->
|
||||
|
||||
<!-- Servlet for injected backends actions -->
|
||||
<servlet>
|
||||
<display-name>BsaServlet</display-name>
|
||||
<servlet-name>bsa-servlet</servlet-name>
|
||||
<servlet-class>google.registry.module.bsa.BsaServlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<!-- Download action -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>bsa-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/bsaDownload</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Refresh action -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>bsa-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/bsaRefresh</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Refresh action -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>bsa-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/bsaValidate</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Upload unavailable domains to BSA action -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>bsa-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/uploadBsaUnavailableNames</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Security config -->
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>Internal</web-resource-name>
|
||||
<description>
|
||||
Admin-only internal section. Requests for paths covered by the URL patterns below will be
|
||||
checked for a logged-in user account that's allowed to access the AppEngine admin console
|
||||
(NOTE: this includes Editor/Viewer permissions in addition to Owner and the new IAM
|
||||
App Engine Admin role. See https://cloud.google.com/appengine/docs/java/access-control
|
||||
specifically the "Access handlers that have a login:admin restriction" line.)
|
||||
|
||||
TODO(b/28219927): lift some of these restrictions so that we can allow OAuth authentication
|
||||
for endpoints that need to be accessed by open-source automated processes.
|
||||
</description>
|
||||
|
||||
<!-- Internal AppEngine endpoints. The '_ah' is short for app hosting. -->
|
||||
<url-pattern>/_ah/*</url-pattern>
|
||||
|
||||
<!-- Registrar console (should not be available on non-default module). -->
|
||||
<url-pattern>/registrar*</url-pattern>
|
||||
|
||||
<!-- Verbatim JavaScript sources (only visible to admins for debugging). -->
|
||||
<url-pattern>/assets/sources/*</url-pattern>
|
||||
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>admin</role-name>
|
||||
</auth-constraint>
|
||||
|
||||
<!-- Repeated here since catch-all rule below is not inherited. -->
|
||||
<user-data-constraint>
|
||||
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
||||
</user-data-constraint>
|
||||
</security-constraint>
|
||||
|
||||
<!-- Require TLS on all requests. -->
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>Secure</web-resource-name>
|
||||
<description>
|
||||
Require encryption for all paths. http URLs will be redirected to https.
|
||||
</description>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</web-resource-collection>
|
||||
<user-data-constraint>
|
||||
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
||||
</user-data-constraint>
|
||||
</security-constraint>
|
||||
</web-app>
|
||||
@@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dispatch-entries>
|
||||
<!-- Send all public-facing unauthenticated traffic to the pubapi service. -->
|
||||
<dispatch>
|
||||
<url>*/rdap/*</url>
|
||||
<module>pubapi</module>
|
||||
</dispatch>
|
||||
<dispatch>
|
||||
<url>*/whois/*</url>
|
||||
<module>pubapi</module>
|
||||
</dispatch>
|
||||
<dispatch>
|
||||
<url>*/_dr/whois</url>
|
||||
<module>pubapi</module>
|
||||
</dispatch>
|
||||
<dispatch>
|
||||
<url>*/check</url>
|
||||
<module>pubapi</module>
|
||||
</dispatch>
|
||||
<dispatch>
|
||||
<url>*/console/*</url>
|
||||
<module>console</module>
|
||||
</dispatch>
|
||||
<dispatch>
|
||||
<url>*/console</url>
|
||||
<module>console</module>
|
||||
</dispatch>
|
||||
</dispatch-entries>
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
# A default java.util.logging configuration.
|
||||
# (All App Engine logging is through java.util.logging by default).
|
||||
#
|
||||
# To use this configuration, copy it into your application's WEB-INF
|
||||
# folder and add the following to your appengine-web.xml:
|
||||
#
|
||||
# <system-properties>
|
||||
# <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
|
||||
# </system-properties>
|
||||
#
|
||||
|
||||
# Set the default logging level for all loggers to INFO.
|
||||
.level = INFO
|
||||
|
||||
# Turn off logging in Hibernate classes for misleading ERROR-level logs
|
||||
org.hibernate.orm.jdbc.batch.level=OFF
|
||||
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.level=OFF
|
||||
@@ -1,66 +0,0 @@
|
||||
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
|
||||
version="6.0">
|
||||
<!-- Servlets -->
|
||||
|
||||
<!-- Servlet for injected frontend actions -->
|
||||
<servlet>
|
||||
<display-name>FrontendServlet</display-name>
|
||||
<servlet-name>frontend-servlet</servlet-name>
|
||||
<servlet-class>google.registry.module.frontend.FrontendServlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<!-- The primary EPP endpoint for the Registry, which accepts EPP requests from our TLS proxy. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>frontend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/epp</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Registrar console endpoints -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>frontend-servlet</servlet-name>
|
||||
<url-pattern>/console-api/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Security config -->
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>Internal</web-resource-name>
|
||||
<description>
|
||||
Admin-only internal section. Requests for paths covered by the URL patterns below will be
|
||||
checked for a logged-in user account that's allowed to access the AppEngine admin console
|
||||
(NOTE: this includes Editor/Viewer permissions in addition to Owner and the new IAM
|
||||
App Engine Admin role. See https://cloud.google.com/appengine/docs/java/access-control
|
||||
specifically the "Access handlers that have a login:admin restriction" line.)
|
||||
|
||||
TODO(b/28219927): lift some of these restrictions so that we can allow OAuth authentication
|
||||
for endpoints that need to be accessed by open-source automated processes.
|
||||
</description>
|
||||
<!-- Internal AppEngine endpoints. The '_ah' is short for app hosting. -->
|
||||
<url-pattern>/_ah/*</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>admin</role-name>
|
||||
</auth-constraint>
|
||||
<!-- Repeated here since catch-all rule below is not inherited. -->
|
||||
<user-data-constraint>
|
||||
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
||||
</user-data-constraint>
|
||||
</security-constraint>
|
||||
|
||||
<!-- Require TLS on all requests. -->
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>Secure</web-resource-name>
|
||||
<description>
|
||||
Require encryption for all paths. http URLs will be redirected to https.
|
||||
</description>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</web-resource-collection>
|
||||
<user-data-constraint>
|
||||
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
||||
</user-data-constraint>
|
||||
</security-constraint>
|
||||
</web-app>
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
# A default java.util.logging configuration.
|
||||
# (All App Engine logging is through java.util.logging by default).
|
||||
#
|
||||
# To use this configuration, copy it into your application's WEB-INF
|
||||
# folder and add the following to your appengine-web.xml:
|
||||
#
|
||||
# <system-properties>
|
||||
# <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
|
||||
# </system-properties>
|
||||
#
|
||||
|
||||
# Set the default logging level for all loggers to INFO.
|
||||
.level = INFO
|
||||
|
||||
# Turn off logging in Hibernate classes for misleading ERROR-level logs
|
||||
org.hibernate.orm.jdbc.batch.level=OFF
|
||||
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.level=OFF
|
||||
@@ -1,102 +0,0 @@
|
||||
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
|
||||
version="6.0">
|
||||
<!-- Servlets -->
|
||||
|
||||
<!-- Servlet for injected frontend actions -->
|
||||
<servlet>
|
||||
<display-name>PubApiServlet</display-name>
|
||||
<servlet-name>pubapi-servlet</servlet-name>
|
||||
<servlet-class>google.registry.module.pubapi.PubApiServlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<!-- HTTP WHOIS. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>pubapi-servlet</servlet-name>
|
||||
<url-pattern>/whois/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Protocol WHOIS. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>pubapi-servlet</servlet-name>
|
||||
<url-pattern>/_dr/whois</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- RDAP (new WHOIS). -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>pubapi-servlet</servlet-name>
|
||||
<url-pattern>/rdap/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Public API to do availability checks -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>pubapi-servlet</servlet-name>
|
||||
<url-pattern>/check</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Security config -->
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>Internal</web-resource-name>
|
||||
<description>
|
||||
Admin-only internal section. Requests for paths covered by the URL patterns below will be
|
||||
checked for a logged-in user account that's allowed to access the AppEngine admin console
|
||||
(NOTE: this includes Editor/Viewer permissions in addition to Owner and the new IAM
|
||||
App Engine Admin role. See https://cloud.google.com/appengine/docs/java/access-control
|
||||
specifically the "Access handlers that have a login:admin restriction" line.)
|
||||
|
||||
TODO(b/28219927): lift some of these restrictions so that we can allow OAuth authentication
|
||||
for endpoints that need to be accessed by open-source automated processes.
|
||||
</description>
|
||||
|
||||
<!-- Internal AppEngine endpoints. The '_ah' is short for app hosting. -->
|
||||
<url-pattern>/_ah/*</url-pattern>
|
||||
|
||||
<!-- Verbatim JavaScript sources (only visible to admins for debugging). -->
|
||||
<url-pattern>/assets/sources/*</url-pattern>
|
||||
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>admin</role-name>
|
||||
</auth-constraint>
|
||||
|
||||
<!-- Repeated here since catch-all rule below is not inherited. -->
|
||||
<user-data-constraint>
|
||||
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
||||
</user-data-constraint>
|
||||
</security-constraint>
|
||||
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>Registrar console</web-resource-name>
|
||||
<description>
|
||||
Registrar console requires user login. This is in addition to the
|
||||
code-level "requireLogin" configuration on individual @Actions.
|
||||
</description>
|
||||
<url-pattern>/registrar*</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>*</role-name>
|
||||
</auth-constraint>
|
||||
<!-- Repeated here since catch-all rule below is not inherited. -->
|
||||
<user-data-constraint>
|
||||
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
||||
</user-data-constraint>
|
||||
</security-constraint>
|
||||
|
||||
<!-- Require TLS on all requests. -->
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>Secure</web-resource-name>
|
||||
<description>
|
||||
Require encryption for all paths. http URLs will be redirected to https.
|
||||
</description>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</web-resource-collection>
|
||||
<user-data-constraint>
|
||||
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
||||
</user-data-constraint>
|
||||
</security-constraint>
|
||||
</web-app>
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
# A default java.util.logging configuration.
|
||||
# (All App Engine logging is through java.util.logging by default).
|
||||
#
|
||||
# To use this configuration, copy it into your application's WEB-INF
|
||||
# folder and add the following to your appengine-web.xml:
|
||||
#
|
||||
# <system-properties>
|
||||
# <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
|
||||
# </system-properties>
|
||||
#
|
||||
|
||||
# Set the default logging level for all loggers to INFO.
|
||||
.level = INFO
|
||||
|
||||
# Turn off logging in Hibernate classes for misleading ERROR-level logs
|
||||
org.hibernate.orm.jdbc.batch.level=OFF
|
||||
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.level=OFF
|
||||
@@ -1,120 +0,0 @@
|
||||
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
|
||||
version="6.0">
|
||||
<!-- Servlets -->
|
||||
|
||||
<!-- Servlet for injected tools actions -->
|
||||
<servlet>
|
||||
<display-name>ToolsServlet</display-name>
|
||||
<servlet-name>tools-servlet</servlet-name>
|
||||
<servlet-class>google.registry.module.tools.ToolsServlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>tools-servlet</servlet-name>
|
||||
<url-pattern>/_dr/admin/updateUserGroup</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>tools-servlet</servlet-name>
|
||||
<url-pattern>/_dr/admin/verifyOte</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>tools-servlet</servlet-name>
|
||||
<url-pattern>/_dr/admin/createGroups</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>tools-servlet</servlet-name>
|
||||
<url-pattern>/_dr/admin/createPremiumList</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>tools-servlet</servlet-name>
|
||||
<url-pattern>/_dr/admin/list/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>tools-servlet</servlet-name>
|
||||
<url-pattern>/_dr/admin/deleteEntity</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>tools-servlet</servlet-name>
|
||||
<url-pattern>/_dr/admin/updatePremiumList</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>tools-servlet</servlet-name>
|
||||
<url-pattern>/_dr/loadtest</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- ExecuteEppCommand uses this to execute remotely. -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>tools-servlet</servlet-name>
|
||||
<url-pattern>/_dr/epptool</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Refreshes all active domains in DNS -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>tools-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/refreshDnsForAllDomains</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>tools-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/generateZoneFiles</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Security config -->
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>Internal</web-resource-name>
|
||||
<description>
|
||||
Admin-only internal section. Requests for paths covered by the URL patterns below will be
|
||||
checked for a logged-in user account that's allowed to access the AppEngine admin console
|
||||
(NOTE: this includes Editor/Viewer permissions in addition to Owner and the new IAM
|
||||
App Engine Admin role. See https://cloud.google.com/appengine/docs/java/access-control
|
||||
specifically the "Access handlers that have a login:admin restriction" line.)
|
||||
|
||||
TODO(b/28219927): lift some of these restrictions so that we can allow OAuth authentication
|
||||
for endpoints that need to be accessed by open-source automated processes.
|
||||
</description>
|
||||
|
||||
<!-- Internal AppEngine endpoints. The '_ah' is short for app hosting. -->
|
||||
<url-pattern>/_ah/*</url-pattern>
|
||||
|
||||
<!-- Registrar console (should not be available on non-default module). -->
|
||||
<url-pattern>/registrar*</url-pattern>
|
||||
|
||||
<!-- Verbatim JavaScript sources (only visible to admins for debugging). -->
|
||||
<url-pattern>/assets/sources/*</url-pattern>
|
||||
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>admin</role-name>
|
||||
</auth-constraint>
|
||||
|
||||
<!-- Repeated here since catch-all rule below is not inherited. -->
|
||||
<user-data-constraint>
|
||||
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
||||
</user-data-constraint>
|
||||
</security-constraint>
|
||||
|
||||
<!-- Require TLS on all requests. -->
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>Secure</web-resource-name>
|
||||
<description>
|
||||
Require encryption for all paths. http URLs will be redirected to https.
|
||||
</description>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</web-resource-collection>
|
||||
<user-data-constraint>
|
||||
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
||||
</user-data-constraint>
|
||||
</security-constraint>
|
||||
</web-app>
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>backend</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>10</max-instances>
|
||||
<idle-timeout>10m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="crash"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1m"/>
|
||||
</static-files>
|
||||
</appengine-web-app>
|
||||
@@ -1,34 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>bsa</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>10</max-instances>
|
||||
<idle-timeout>10m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="crash"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<!-- Enable external traffic to go through VPC, required for static ip -->
|
||||
<vpc-access-connector>
|
||||
<name>projects/domain-registry-crash/locations/us-central1/connectors/appengine-connector</name>
|
||||
<egress-setting>all-traffic</egress-setting>
|
||||
</vpc-access-connector>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1m"/>
|
||||
</static-files>
|
||||
</appengine-web-app>
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>default</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4_1G</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>10</max-instances>
|
||||
<idle-timeout>30m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="crash"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1m"/>
|
||||
<include path="/registrar/*.html" expiration="1m"/>
|
||||
</static-files>
|
||||
</appengine-web-app>
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>pubapi</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>8</max-instances>
|
||||
<idle-timeout>10m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="crash"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1m"/>
|
||||
<include path="/assets/js/**" expiration="1m"/>
|
||||
<include path="/assets/css/**" expiration="1m"/>
|
||||
<include path="/assets/images/**" expiration="1m"/>
|
||||
</static-files>
|
||||
</appengine-web-app>
|
||||
@@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>tools</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>10</max-instances>
|
||||
<idle-timeout>10m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="crash"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1m"/>
|
||||
<include path="/assets/js/**" expiration="1m"/>
|
||||
<include path="/assets/css/**" expiration="1m"/>
|
||||
<include path="/assets/images/**" expiration="1m"/>
|
||||
</static-files>
|
||||
</appengine-web-app>
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>backend</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>10</max-instances>
|
||||
<idle-timeout>10m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="local"/>
|
||||
<property name="appengine.generated.dir"
|
||||
value="/tmp/domain-registry-appengine-generated/local/"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html">
|
||||
<http-header name="Cache-Control" value="max-age=0,must-revalidate" />
|
||||
</include>
|
||||
</static-files>
|
||||
</appengine-web-app>
|
||||
@@ -1,32 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>bsa</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>10</max-instances>
|
||||
<idle-timeout>10m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="local"/>
|
||||
<property name="appengine.generated.dir"
|
||||
value="/tmp/domain-registry-appengine-generated/local/"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html">
|
||||
<http-header name="Cache-Control" value="max-age=0,must-revalidate" />
|
||||
</include>
|
||||
</static-files>
|
||||
</appengine-web-app>
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>default</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4_1G</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>10</max-instances>
|
||||
<idle-timeout>10m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="local"/>
|
||||
<property name="appengine.generated.dir"
|
||||
value="/tmp/domain-registry-appengine-generated/local/"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html">
|
||||
<http-header name="Cache-Control" value="max-age=0,must-revalidate" />
|
||||
</include>
|
||||
<include path="/registrar/*.html">
|
||||
<http-header name="Cache-Control" value="max-age=0,must-revalidate" />
|
||||
</include>
|
||||
</static-files>
|
||||
</appengine-web-app>
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>pubapi</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>8</max-instances>
|
||||
<idle-timeout>10m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="local"/>
|
||||
<property name="appengine.generated.dir"
|
||||
value="/tmp/domain-registry-appengine-generated/local/"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html">
|
||||
<http-header name="Cache-Control" value="max-age=0,must-revalidate" />
|
||||
</include>
|
||||
<include path="/assets/js/**">
|
||||
<http-header name="Cache-Control" value="max-age=0,must-revalidate" />
|
||||
</include>
|
||||
<include path="/assets/css/**">
|
||||
<http-header name="Cache-Control" value="max-age=0,must-revalidate" />
|
||||
</include>
|
||||
<include path="/assets/images/**">
|
||||
<http-header name="Cache-Control" value="max-age=0,must-revalidate" />
|
||||
</include>
|
||||
</static-files>
|
||||
</appengine-web-app>
|
||||
@@ -1,41 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>tools</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>10</max-instances>
|
||||
<idle-timeout>10m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="local"/>
|
||||
<property name="appengine.generated.dir"
|
||||
value="/tmp/domain-registry-appengine-generated/local/"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html">
|
||||
<http-header name="Cache-Control" value="max-age=0,must-revalidate" />
|
||||
</include>
|
||||
<include path="/assets/js/**">
|
||||
<http-header name="Cache-Control" value="max-age=0,must-revalidate" />
|
||||
</include>
|
||||
<include path="/assets/css/**">
|
||||
<http-header name="Cache-Control" value="max-age=0,must-revalidate" />
|
||||
</include>
|
||||
<include path="/assets/images/**">
|
||||
<http-header name="Cache-Control" value="max-age=0,must-revalidate" />
|
||||
</include>
|
||||
</static-files>
|
||||
</appengine-web-app>
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>backend</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4_1G</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>100</max-instances>
|
||||
<idle-timeout>10m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="production"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1d"/>
|
||||
</static-files>
|
||||
|
||||
<!-- Prevent uncaught servlet errors from leaking a stack trace. -->
|
||||
<static-error-handlers>
|
||||
<handler file="error.html"/>
|
||||
</static-error-handlers>
|
||||
</appengine-web-app>
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>bsa</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4_1G</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>3</max-instances>
|
||||
<idle-timeout>60m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="production"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<!-- Enable external traffic to go through VPC, required for static ip -->
|
||||
<vpc-access-connector>
|
||||
<name>projects/domain-registry/locations/us-central1/connectors/appengine-connector</name>
|
||||
<egress-setting>all-traffic</egress-setting>
|
||||
</vpc-access-connector>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1d"/>
|
||||
</static-files>
|
||||
|
||||
<!-- Prevent uncaught servlet errors from leaking a stack trace. -->
|
||||
<static-error-handlers>
|
||||
<handler file="error.html"/>
|
||||
</static-error-handlers>
|
||||
</appengine-web-app>
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>default</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4_1G</instance-class>
|
||||
<manual-scaling>
|
||||
<instances>24</instances>
|
||||
</manual-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="production"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1d"/>
|
||||
<include path="/registrar/*.html" expiration="1d"/>
|
||||
</static-files>
|
||||
|
||||
<!-- Prevent uncaught servlet errors from leaking a stack trace. -->
|
||||
<static-error-handlers>
|
||||
<handler file="error.html"/>
|
||||
</static-error-handlers>
|
||||
</appengine-web-app>
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>pubapi</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4_1G</instance-class>
|
||||
<manual-scaling>
|
||||
<instances>24</instances>
|
||||
</manual-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="production"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1d"/>
|
||||
<include path="/assets/js/**" expiration="1d"/>
|
||||
<include path="/assets/css/**" expiration="1d"/>
|
||||
<include path="/assets/images/**" expiration="1d"/>
|
||||
</static-files>
|
||||
|
||||
<!-- Prevent uncaught servlet errors from leaking a stack trace. -->
|
||||
<static-error-handlers>
|
||||
<handler file="error.html"/>
|
||||
</static-error-handlers>
|
||||
</appengine-web-app>
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>tools</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4_1G</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>5</max-instances>
|
||||
<idle-timeout>60m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="production"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1d"/>
|
||||
<include path="/assets/js/**" expiration="1d"/>
|
||||
<include path="/assets/css/**" expiration="1d"/>
|
||||
<include path="/assets/images/**" expiration="1d"/>
|
||||
</static-files>
|
||||
|
||||
<!-- Prevent uncaught servlet errors from leaking a stack trace. -->
|
||||
<static-error-handlers>
|
||||
<handler file="error.html"/>
|
||||
</static-error-handlers>
|
||||
</appengine-web-app>
|
||||
@@ -1,33 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>backend</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>10</max-instances>
|
||||
<idle-timeout>10m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="qa"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1h"/>
|
||||
</static-files>
|
||||
|
||||
<!-- Prevent uncaught servlet errors from leaking a stack trace. -->
|
||||
<static-error-handlers>
|
||||
<handler file="error.html"/>
|
||||
</static-error-handlers>
|
||||
</appengine-web-app>
|
||||
@@ -1,39 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>bsa</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>10</max-instances>
|
||||
<idle-timeout>10m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="qa"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1h"/>
|
||||
</static-files>
|
||||
|
||||
<!-- Enable external traffic to go through VPC, required for static ip -->
|
||||
<vpc-access-connector>
|
||||
<name>projects/domain-registry-qa/locations/us-central1/connectors/appengine-connector</name>
|
||||
<egress-setting>all-traffic</egress-setting>
|
||||
</vpc-access-connector>
|
||||
|
||||
<!-- Prevent uncaught servlet errors from leaking a stack trace. -->
|
||||
<static-error-handlers>
|
||||
<handler file="error.html"/>
|
||||
</static-error-handlers>
|
||||
</appengine-web-app>
|
||||
@@ -1,37 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>default</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>F4_1G</instance-class>
|
||||
<automatic-scaling>
|
||||
<min-idle-instances>1</min-idle-instances>
|
||||
<max-idle-instances>automatic</max-idle-instances>
|
||||
<min-pending-latency>automatic</min-pending-latency>
|
||||
<max-pending-latency>100ms</max-pending-latency>
|
||||
<max-concurrent-requests>10</max-concurrent-requests>
|
||||
</automatic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="qa"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1h"/>
|
||||
<include path="/registrar/*.html" expiration="1h"/>
|
||||
</static-files>
|
||||
|
||||
<!-- Prevent uncaught servlet errors from leaking a stack trace. -->
|
||||
<static-error-handlers>
|
||||
<handler file="error.html"/>
|
||||
</static-error-handlers>
|
||||
</appengine-web-app>
|
||||
@@ -1,36 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>pubapi</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>10</max-instances>
|
||||
<idle-timeout>10m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="qa"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1h"/>
|
||||
<include path="/assets/js/**" expiration="1h"/>
|
||||
<include path="/assets/css/**" expiration="1h"/>
|
||||
<include path="/assets/images/**" expiration="1h"/>
|
||||
</static-files>
|
||||
|
||||
<!-- Prevent uncaught servlet errors from leaking a stack trace. -->
|
||||
<static-error-handlers>
|
||||
<handler file="error.html"/>
|
||||
</static-error-handlers>
|
||||
</appengine-web-app>
|
||||
@@ -1,36 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>tools</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>10</max-instances>
|
||||
<idle-timeout>10m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="qa"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1h"/>
|
||||
<include path="/assets/js/**" expiration="1h"/>
|
||||
<include path="/assets/css/**" expiration="1h"/>
|
||||
<include path="/assets/images/**" expiration="1h"/>
|
||||
</static-files>
|
||||
|
||||
<!-- Prevent uncaught servlet errors from leaking a stack trace. -->
|
||||
<static-error-handlers>
|
||||
<handler file="error.html"/>
|
||||
</static-error-handlers>
|
||||
</appengine-web-app>
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>backend</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>100</max-instances>
|
||||
<idle-timeout>10m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="sandbox"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1d"/>
|
||||
</static-files>
|
||||
|
||||
<!-- Prevent uncaught servlet errors from leaking a stack trace. -->
|
||||
<static-error-handlers>
|
||||
<handler file="error.html"/>
|
||||
</static-error-handlers>
|
||||
</appengine-web-app>
|
||||
@@ -1,39 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>bsa</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>3</max-instances>
|
||||
<idle-timeout>60m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="sandbox"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1d"/>
|
||||
</static-files>
|
||||
|
||||
<!-- Enable external traffic to go through VPC, required for static ip -->
|
||||
<vpc-access-connector>
|
||||
<name>projects/domain-registry-sandbox/locations/us-central1/connectors/appengine-connector</name>
|
||||
<egress-setting>all-traffic</egress-setting>
|
||||
</vpc-access-connector>
|
||||
|
||||
<!-- Prevent uncaught servlet errors from leaking a stack trace. -->
|
||||
<static-error-handlers>
|
||||
<handler file="error.html"/>
|
||||
</static-error-handlers>
|
||||
</appengine-web-app>
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>default</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4_1G</instance-class>
|
||||
<manual-scaling>
|
||||
<instances>6</instances>
|
||||
</manual-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="sandbox"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1d"/>
|
||||
<include path="/registrar/*.html" expiration="1d"/>
|
||||
</static-files>
|
||||
|
||||
<!-- Prevent uncaught servlet errors from leaking a stack trace. -->
|
||||
<static-error-handlers>
|
||||
<handler file="error.html"/>
|
||||
</static-error-handlers>
|
||||
</appengine-web-app>
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>pubapi</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4_1G</instance-class>
|
||||
<manual-scaling>
|
||||
<instances>5</instances>
|
||||
</manual-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="sandbox"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1d"/>
|
||||
<include path="/assets/js/**" expiration="1d"/>
|
||||
<include path="/assets/css/**" expiration="1d"/>
|
||||
<include path="/assets/images/**" expiration="1d"/>
|
||||
</static-files>
|
||||
|
||||
<!-- Prevent uncaught servlet errors from leaking a stack trace. -->
|
||||
<static-error-handlers>
|
||||
<handler file="error.html"/>
|
||||
</static-error-handlers>
|
||||
</appengine-web-app>
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
|
||||
|
||||
<runtime>java21</runtime>
|
||||
<service>tools</service>
|
||||
<app-engine-apis>true</app-engine-apis>
|
||||
<sessions-enabled>true</sessions-enabled>
|
||||
<instance-class>B4</instance-class>
|
||||
<basic-scaling>
|
||||
<max-instances>5</max-instances>
|
||||
<idle-timeout>60m</idle-timeout>
|
||||
</basic-scaling>
|
||||
|
||||
<system-properties>
|
||||
<property name="java.util.logging.config.file"
|
||||
value="WEB-INF/logging.properties"/>
|
||||
<property name="google.registry.environment"
|
||||
value="sandbox"/>
|
||||
</system-properties>
|
||||
|
||||
<env-variables>
|
||||
<env-var name="GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE" value="true"/>
|
||||
</env-variables>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1d"/>
|
||||
<include path="/assets/js/**" expiration="1d"/>
|
||||
<include path="/assets/css/**" expiration="1d"/>
|
||||
<include path="/assets/images/**" expiration="1d"/>
|
||||
</static-files>
|
||||
|
||||
<!-- Prevent uncaught servlet errors from leaking a stack trace. -->
|
||||
<static-error-handlers>
|
||||
<handler file="error.html"/>
|
||||
</static-error-handlers>
|
||||
</appengine-web-app>
|
||||
@@ -128,10 +128,10 @@ class SyncRegistrarsSheet {
|
||||
builder.put("billingContacts", convertContacts(contacts, byType(BILLING)));
|
||||
builder.put(
|
||||
"contactsMarkedAsWhoisAdmin",
|
||||
convertContacts(contacts, RegistrarPoc::getVisibleInWhoisAsAdmin));
|
||||
convertContacts(contacts, RegistrarPoc::getVisibleInRdapAsAdmin));
|
||||
builder.put(
|
||||
"contactsMarkedAsWhoisTech",
|
||||
convertContacts(contacts, RegistrarPoc::getVisibleInWhoisAsTech));
|
||||
convertContacts(contacts, RegistrarPoc::getVisibleInRdapAsTech));
|
||||
builder.put("emailAddress", convert(registrar.getEmailAddress()));
|
||||
builder.put("address.street", convert(address.getStreet()));
|
||||
builder.put("address.city", convert(address.getCity()));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<version comment="Latin LGR">1</version>
|
||||
<date>2025-10-01</date>
|
||||
<language>und-Latn</language>
|
||||
<unicode-version>2</unicode-version>
|
||||
<unicode-version>11.1.0</unicode-version>
|
||||
<description type="text/html"><![CDATA[
|
||||
<div class="instructions">
|
||||
<h2>INSTRUCTIONS</h2>
|
||||
@@ -650,7 +650,6 @@
|
||||
<!--Action elements go here - order defines precedence-->
|
||||
<action disp="invalid" match="leading-combining-mark" comment="labels with leading combining marks are invalid ⍟" />
|
||||
<action disp="invalid" any-variant="out-of-repertoire-var" comment="any variant label with a code point out of repertoire is invalid ⍟" />
|
||||
<action disp="invalid" match="dot-L-dot" comment="labels with one L sharing two middle dots are invalid" />
|
||||
<action disp="blocked" any-variant="blocked" comment="any variant label containing blocked variants is blocked ⍟" />
|
||||
<action disp="allocatable" all-variants="allocatable" comment="variant labels with all variants allocatable are allocatable ⍟" />
|
||||
<action disp="allocatable" all-variants="fallback" comment="any label with all variants of type fallback is allocatable ⍟" />
|
||||
|
||||
@@ -192,7 +192,7 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
|
||||
immutableEnumSet(State.ACTIVE, State.SUSPENDED);
|
||||
|
||||
/**
|
||||
* The types for which a {@link Registrar} should be included in WHOIS and RDAP output. We exclude
|
||||
* The types for which a {@link Registrar} should be included in RDAP output. We exclude
|
||||
* registrars of type TEST. We considered excluding INTERNAL as well, but decided that
|
||||
* troubleshooting would be easier with INTERNAL registrars visible. Before removing other types
|
||||
* from view, carefully consider the effect on things like prober monitoring and OT&E.
|
||||
@@ -416,13 +416,13 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
|
||||
String phonePasscode;
|
||||
|
||||
/**
|
||||
* A dirty bit for whether RegistrarContact changes have been made that haven't been synced to
|
||||
* Google Groups yet. When creating a new instance, contacts require syncing by default.
|
||||
* A dirty bit for whether RegistrarPoc changes have been made that haven't been synced to Google
|
||||
* Groups yet. When creating a new instance, contacts require syncing by default.
|
||||
*/
|
||||
@Column(nullable = false)
|
||||
boolean contactsRequireSyncing = true;
|
||||
|
||||
/** Whether or not registry lock is allowed for this registrar. */
|
||||
/** Whether registry lock is allowed for this registrar. */
|
||||
@Column(nullable = false)
|
||||
@Expose
|
||||
boolean registryLockAllowed = false;
|
||||
@@ -612,11 +612,11 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link RegistrarPoc} that is the WHOIS abuse contact for this registrar, or empty
|
||||
* if one does not exist.
|
||||
* Returns the {@link RegistrarPoc} that is the RDAP abuse contact for this registrar, or empty if
|
||||
* one does not exist.
|
||||
*/
|
||||
public Optional<RegistrarPoc> getWhoisAbuseContact() {
|
||||
return getContacts().stream().filter(RegistrarPoc::getVisibleInDomainWhoisAsAbuse).findFirst();
|
||||
public Optional<RegistrarPoc> getRdapAbuseContact() {
|
||||
return getContacts().stream().filter(RegistrarPoc::getVisibleInDomainRdapAsAbuse).findFirst();
|
||||
}
|
||||
|
||||
private ImmutableList<RegistrarPoc> getPocs(TransactionManager txnManager) {
|
||||
|
||||
@@ -48,9 +48,9 @@ import java.util.Set;
|
||||
* A contact for a Registrar. Note, equality, hashCode and comparable have been overridden to only
|
||||
* enable key equality.
|
||||
*
|
||||
* <p>IMPORTANT NOTE: Any time that you change, update, or delete RegistrarContact entities, you
|
||||
* *MUST* also modify the persisted Registrar entity with {@link Registrar#contactsRequireSyncing}
|
||||
* set to true.
|
||||
* <p>IMPORTANT NOTE: Any time that you change, update, or delete RegistrarPoc entities, you *MUST*
|
||||
* also modify the persisted Registrar entity with {@link Registrar#contactsRequireSyncing} set to
|
||||
* true.
|
||||
*/
|
||||
@Entity
|
||||
@IdClass(RegistrarPoc.RegistrarPocId.class)
|
||||
@@ -58,8 +58,8 @@ public class RegistrarPoc extends ImmutableObject implements Jsonifiable, Unsafe
|
||||
/**
|
||||
* Registrar contacts types for partner communication tracking.
|
||||
*
|
||||
* <p><b>Note:</b> These types only matter to the registry. They are not meant to be used for
|
||||
* WHOIS or RDAP results.
|
||||
* <p><b>Note:</b> These types only matter to the registry. They are not meant to be used for RDAP
|
||||
* results.
|
||||
*/
|
||||
public enum Type {
|
||||
ABUSE("abuse", true),
|
||||
@@ -115,32 +115,23 @@ public class RegistrarPoc extends ImmutableObject implements Jsonifiable, Unsafe
|
||||
@Expose
|
||||
Set<Type> types;
|
||||
|
||||
/**
|
||||
* Whether this contact is publicly visible in WHOIS registrar query results as an Admin contact.
|
||||
*/
|
||||
@Column(nullable = false)
|
||||
/** If this contact is publicly visible in RDAP registrar query results as an Admin contact */
|
||||
@Column(nullable = false, name = "visibleInWhoisAsAdmin")
|
||||
@Expose
|
||||
boolean visibleInWhoisAsAdmin = false;
|
||||
boolean visibleInRdapAsAdmin = false;
|
||||
|
||||
/** If this contact is publicly visible in RDAP registrar query results as a Technical contact */
|
||||
@Column(nullable = false, name = "visibleInWhoisAsTech")
|
||||
@Expose
|
||||
boolean visibleInRdapAsTech = false;
|
||||
|
||||
/**
|
||||
* Whether this contact is publicly visible in WHOIS registrar query results as a Technical
|
||||
* contact.
|
||||
*/
|
||||
@Column(nullable = false)
|
||||
@Expose
|
||||
boolean visibleInWhoisAsTech = false;
|
||||
|
||||
/**
|
||||
* Whether this contact's phone number and email address is publicly visible in WHOIS domain query
|
||||
* If this contact's phone number and email address are publicly visible in RDAP domain query
|
||||
* results as registrar abuse contact info.
|
||||
*/
|
||||
@Column(nullable = false)
|
||||
@Column(nullable = false, name = "visibleInDomainWhoisAsAbuse")
|
||||
@Expose
|
||||
boolean visibleInDomainWhoisAsAbuse = false;
|
||||
|
||||
/** Legacy field, around until we can remove the non-null constraint and the column from SQL. */
|
||||
@Column(nullable = false)
|
||||
boolean allowedToSetRegistryLockPassword = false;
|
||||
boolean visibleInDomainRdapAsAbuse = false;
|
||||
|
||||
/**
|
||||
* Helper to update the contacts associated with a Registrar. This requires querying for the
|
||||
@@ -188,16 +179,16 @@ public class RegistrarPoc extends ImmutableObject implements Jsonifiable, Unsafe
|
||||
return nullToEmptyImmutableSortedCopy(types);
|
||||
}
|
||||
|
||||
public boolean getVisibleInWhoisAsAdmin() {
|
||||
return visibleInWhoisAsAdmin;
|
||||
public boolean getVisibleInRdapAsAdmin() {
|
||||
return visibleInRdapAsAdmin;
|
||||
}
|
||||
|
||||
public boolean getVisibleInWhoisAsTech() {
|
||||
return visibleInWhoisAsTech;
|
||||
public boolean getVisibleInRdapAsTech() {
|
||||
return visibleInRdapAsTech;
|
||||
}
|
||||
|
||||
public boolean getVisibleInDomainWhoisAsAbuse() {
|
||||
return visibleInDomainWhoisAsAbuse;
|
||||
public boolean getVisibleInDomainRdapAsAbuse() {
|
||||
return visibleInDomainRdapAsAbuse;
|
||||
}
|
||||
|
||||
public Builder asBuilder() {
|
||||
@@ -214,8 +205,8 @@ public class RegistrarPoc extends ImmutableObject implements Jsonifiable, Unsafe
|
||||
* person@example.com
|
||||
* Tel: +1.2125650666
|
||||
* Types: [ADMIN, WHOIS]
|
||||
* Visible in WHOIS as Admin contact: Yes
|
||||
* Visible in WHOIS as Technical contact: No
|
||||
* Visible in RDAP as Admin contact: Yes
|
||||
* Visible in RDAP as Technical contact: No
|
||||
* Registrar-Console access: Yes
|
||||
* Login Email Address: person@registry.example
|
||||
* }</pre>
|
||||
@@ -232,18 +223,18 @@ public class RegistrarPoc extends ImmutableObject implements Jsonifiable, Unsafe
|
||||
}
|
||||
result.append("Types: ").append(getTypes()).append('\n');
|
||||
result
|
||||
.append("Visible in registrar WHOIS query as Admin contact: ")
|
||||
.append(getVisibleInWhoisAsAdmin() ? "Yes" : "No")
|
||||
.append("Visible in registrar RDAP query as Admin contact: ")
|
||||
.append(getVisibleInRdapAsAdmin() ? "Yes" : "No")
|
||||
.append('\n');
|
||||
result
|
||||
.append("Visible in registrar WHOIS query as Technical contact: ")
|
||||
.append(getVisibleInWhoisAsTech() ? "Yes" : "No")
|
||||
.append("Visible in registrar RDAP query as Technical contact: ")
|
||||
.append(getVisibleInRdapAsTech() ? "Yes" : "No")
|
||||
.append('\n');
|
||||
result
|
||||
.append(
|
||||
"Phone number and email visible in domain WHOIS query as "
|
||||
"Phone number and email visible in domain RDAP query as "
|
||||
+ "Registrar Abuse contact info: ")
|
||||
.append(getVisibleInDomainWhoisAsAbuse() ? "Yes" : "No")
|
||||
.append(getVisibleInDomainRdapAsAbuse() ? "Yes" : "No")
|
||||
.append('\n');
|
||||
return result.toString();
|
||||
}
|
||||
@@ -256,9 +247,9 @@ public class RegistrarPoc extends ImmutableObject implements Jsonifiable, Unsafe
|
||||
.put("phoneNumber", phoneNumber)
|
||||
.put("faxNumber", faxNumber)
|
||||
.put("types", getTypes().stream().map(Object::toString).collect(joining(",")))
|
||||
.put("visibleInWhoisAsAdmin", visibleInWhoisAsAdmin)
|
||||
.put("visibleInWhoisAsTech", visibleInWhoisAsTech)
|
||||
.put("visibleInDomainWhoisAsAbuse", visibleInDomainWhoisAsAbuse)
|
||||
.put("visibleInRdapAsAdmin", visibleInRdapAsAdmin)
|
||||
.put("visibleInRdapAsTech", visibleInRdapAsTech)
|
||||
.put("visibleInDomainRdapAsAbuse", visibleInDomainRdapAsAbuse)
|
||||
.put("id", getId())
|
||||
.build();
|
||||
}
|
||||
@@ -336,18 +327,18 @@ public class RegistrarPoc extends ImmutableObject implements Jsonifiable, Unsafe
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setVisibleInWhoisAsAdmin(boolean visible) {
|
||||
getInstance().visibleInWhoisAsAdmin = visible;
|
||||
public Builder setVisibleInRdapAsAdmin(boolean visible) {
|
||||
getInstance().visibleInRdapAsAdmin = visible;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setVisibleInWhoisAsTech(boolean visible) {
|
||||
getInstance().visibleInWhoisAsTech = visible;
|
||||
public Builder setVisibleInRdapAsTech(boolean visible) {
|
||||
getInstance().visibleInRdapAsTech = visible;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setVisibleInDomainWhoisAsAbuse(boolean visible) {
|
||||
getInstance().visibleInDomainWhoisAsAbuse = visible;
|
||||
public Builder setVisibleInDomainRdapAsAbuse(boolean visible) {
|
||||
getInstance().visibleInDomainRdapAsAbuse = visible;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,6 @@ import google.registry.request.Modules.UrlConnectionServiceModule;
|
||||
import google.registry.request.RequestHandler;
|
||||
import google.registry.request.auth.AuthModule;
|
||||
import google.registry.request.auth.RequestAuthenticator;
|
||||
import google.registry.ui.ConsoleDebug.ConsoleConfigModule;
|
||||
import google.registry.util.UtilsModule;
|
||||
import jakarta.inject.Provider;
|
||||
import jakarta.inject.Singleton;
|
||||
@@ -63,7 +62,6 @@ import jakarta.inject.Singleton;
|
||||
BigqueryModule.class,
|
||||
CloudTasksUtilsModule.class,
|
||||
ConfigModule.class,
|
||||
ConsoleConfigModule.class,
|
||||
CredentialModule.class,
|
||||
CustomLogicFactoryModule.class,
|
||||
DirectoryModule.class,
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
// Copyright 2023 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.module.bsa;
|
||||
|
||||
import com.google.monitoring.metrics.MetricReporter;
|
||||
import dagger.Component;
|
||||
import dagger.Lazy;
|
||||
import google.registry.config.CredentialModule;
|
||||
import google.registry.config.RegistryConfig.ConfigModule;
|
||||
import google.registry.groups.GmailModule;
|
||||
import google.registry.keyring.KeyringModule;
|
||||
import google.registry.module.bsa.BsaRequestComponent.BsaRequestComponentModule;
|
||||
import google.registry.monitoring.whitebox.StackdriverModule;
|
||||
import google.registry.persistence.PersistenceModule;
|
||||
import google.registry.privileges.secretmanager.SecretManagerModule;
|
||||
import google.registry.request.Modules.GsonModule;
|
||||
import google.registry.request.Modules.UrlConnectionServiceModule;
|
||||
import google.registry.request.auth.AuthModule;
|
||||
import google.registry.util.UtilsModule;
|
||||
import jakarta.inject.Singleton;
|
||||
|
||||
@Singleton
|
||||
@Component(
|
||||
modules = {
|
||||
AuthModule.class,
|
||||
BsaRequestComponentModule.class,
|
||||
ConfigModule.class,
|
||||
CredentialModule.class,
|
||||
GmailModule.class,
|
||||
GsonModule.class,
|
||||
PersistenceModule.class,
|
||||
KeyringModule.class,
|
||||
SecretManagerModule.class,
|
||||
StackdriverModule.class,
|
||||
UrlConnectionServiceModule.class,
|
||||
UtilsModule.class
|
||||
})
|
||||
interface BsaComponent {
|
||||
BsaRequestHandler requestHandler();
|
||||
|
||||
Lazy<MetricReporter> metricReporter();
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
// Copyright 2023 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.module.bsa;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Subcomponent;
|
||||
import google.registry.bsa.BsaDownloadAction;
|
||||
import google.registry.bsa.BsaRefreshAction;
|
||||
import google.registry.bsa.BsaValidateAction;
|
||||
import google.registry.bsa.UploadBsaUnavailableDomainsAction;
|
||||
import google.registry.request.Modules.UrlConnectionServiceModule;
|
||||
import google.registry.request.RequestComponentBuilder;
|
||||
import google.registry.request.RequestModule;
|
||||
import google.registry.request.RequestScope;
|
||||
|
||||
@RequestScope
|
||||
@Subcomponent(modules = {RequestModule.class, UrlConnectionServiceModule.class})
|
||||
public interface BsaRequestComponent {
|
||||
|
||||
BsaDownloadAction bsaDownloadAction();
|
||||
|
||||
BsaRefreshAction bsaRefreshAction();
|
||||
|
||||
BsaValidateAction bsaValidateAction();
|
||||
|
||||
UploadBsaUnavailableDomainsAction uploadBsaUnavailableDomains();
|
||||
|
||||
@Subcomponent.Builder
|
||||
abstract class Builder implements RequestComponentBuilder<BsaRequestComponent> {
|
||||
|
||||
@Override
|
||||
public abstract Builder requestModule(RequestModule requestModule);
|
||||
|
||||
@Override
|
||||
public abstract BsaRequestComponent build();
|
||||
}
|
||||
|
||||
@Module(subcomponents = BsaRequestComponent.class)
|
||||
class BsaRequestComponentModule {}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
// Copyright 2023 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.module.bsa;
|
||||
|
||||
import google.registry.request.RequestHandler;
|
||||
import google.registry.request.auth.RequestAuthenticator;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Provider;
|
||||
|
||||
public class BsaRequestHandler extends RequestHandler<BsaRequestComponent> {
|
||||
@Inject
|
||||
public BsaRequestHandler(
|
||||
Provider<BsaRequestComponent.Builder> componentBuilderProvider,
|
||||
RequestAuthenticator requestAuthenticator) {
|
||||
super(componentBuilderProvider, requestAuthenticator);
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
// Copyright 2023 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.module.bsa;
|
||||
|
||||
import com.google.monitoring.metrics.MetricReporter;
|
||||
import dagger.Lazy;
|
||||
import google.registry.module.ServletBase;
|
||||
|
||||
public final class BsaServlet extends ServletBase {
|
||||
|
||||
private static final BsaComponent component = DaggerBsaComponent.create();
|
||||
private static final BsaRequestHandler requestHandler = component.requestHandler();
|
||||
private static final Lazy<MetricReporter> metricReporter = component.metricReporter();
|
||||
|
||||
public BsaServlet() {
|
||||
super(requestHandler, metricReporter);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
// Copyright 2023 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
@javax.annotation.ParametersAreNonnullByDefault
|
||||
package google.registry.module.bsa;
|
||||
@@ -35,7 +35,6 @@ import google.registry.privileges.secretmanager.SecretManagerModule;
|
||||
import google.registry.request.Modules.GsonModule;
|
||||
import google.registry.request.Modules.NetHttpTransportModule;
|
||||
import google.registry.request.auth.AuthModule;
|
||||
import google.registry.ui.ConsoleDebug.ConsoleConfigModule;
|
||||
import google.registry.util.UtilsModule;
|
||||
import jakarta.inject.Singleton;
|
||||
|
||||
@@ -46,7 +45,6 @@ import jakarta.inject.Singleton;
|
||||
AuthModule.class,
|
||||
CloudTasksUtilsModule.class,
|
||||
ConfigModule.class,
|
||||
ConsoleConfigModule.class,
|
||||
CredentialModule.class,
|
||||
CustomLogicFactoryModule.class,
|
||||
CloudTasksUtilsModule.class,
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
// Copyright 2018 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.module.pubapi;
|
||||
|
||||
import com.google.monitoring.metrics.MetricReporter;
|
||||
import dagger.Component;
|
||||
import dagger.Lazy;
|
||||
import google.registry.config.CredentialModule;
|
||||
import google.registry.config.RegistryConfig.ConfigModule;
|
||||
import google.registry.flows.ServerTridProviderModule;
|
||||
import google.registry.flows.custom.CustomLogicFactoryModule;
|
||||
import google.registry.groups.DirectoryModule;
|
||||
import google.registry.groups.GroupsModule;
|
||||
import google.registry.groups.GroupssettingsModule;
|
||||
import google.registry.keyring.KeyringModule;
|
||||
import google.registry.keyring.api.KeyModule;
|
||||
import google.registry.module.pubapi.PubApiRequestComponent.PubApiRequestComponentModule;
|
||||
import google.registry.monitoring.whitebox.StackdriverModule;
|
||||
import google.registry.persistence.PersistenceModule;
|
||||
import google.registry.privileges.secretmanager.SecretManagerModule;
|
||||
import google.registry.request.Modules.GsonModule;
|
||||
import google.registry.request.Modules.NetHttpTransportModule;
|
||||
import google.registry.request.auth.AuthModule;
|
||||
import google.registry.util.UtilsModule;
|
||||
import jakarta.inject.Singleton;
|
||||
|
||||
/** Dagger component with instance lifetime for "pubapi" App Engine module. */
|
||||
@Singleton
|
||||
@Component(
|
||||
modules = {
|
||||
AuthModule.class,
|
||||
ConfigModule.class,
|
||||
CredentialModule.class,
|
||||
CustomLogicFactoryModule.class,
|
||||
DirectoryModule.class,
|
||||
GroupsModule.class,
|
||||
GroupssettingsModule.class,
|
||||
GsonModule.class,
|
||||
KeyModule.class,
|
||||
KeyringModule.class,
|
||||
NetHttpTransportModule.class,
|
||||
PersistenceModule.class,
|
||||
PubApiRequestComponentModule.class,
|
||||
SecretManagerModule.class,
|
||||
ServerTridProviderModule.class,
|
||||
StackdriverModule.class,
|
||||
UtilsModule.class
|
||||
})
|
||||
interface PubApiComponent {
|
||||
PubApiRequestHandler requestHandler();
|
||||
|
||||
Lazy<MetricReporter> metricReporter();
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
// Copyright 2018 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.module.pubapi;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Subcomponent;
|
||||
import google.registry.dns.DnsModule;
|
||||
import google.registry.flows.CheckApiAction;
|
||||
import google.registry.flows.CheckApiAction.CheckApiModule;
|
||||
import google.registry.flows.TlsCredentials.EppTlsModule;
|
||||
import google.registry.module.ReadinessProbeAction.ReadinessProbeActionPubApi;
|
||||
import google.registry.monitoring.whitebox.WhiteboxModule;
|
||||
import google.registry.rdap.RdapAutnumAction;
|
||||
import google.registry.rdap.RdapDomainAction;
|
||||
import google.registry.rdap.RdapDomainSearchAction;
|
||||
import google.registry.rdap.RdapEmptyAction;
|
||||
import google.registry.rdap.RdapEntityAction;
|
||||
import google.registry.rdap.RdapEntitySearchAction;
|
||||
import google.registry.rdap.RdapHelpAction;
|
||||
import google.registry.rdap.RdapIpAction;
|
||||
import google.registry.rdap.RdapModule;
|
||||
import google.registry.rdap.RdapNameserverAction;
|
||||
import google.registry.rdap.RdapNameserverSearchAction;
|
||||
import google.registry.request.RequestComponentBuilder;
|
||||
import google.registry.request.RequestModule;
|
||||
import google.registry.request.RequestScope;
|
||||
|
||||
/** Dagger component with per-request lifetime for "pubapi" App Engine module. */
|
||||
@RequestScope
|
||||
@Subcomponent(
|
||||
modules = {
|
||||
CheckApiModule.class,
|
||||
DnsModule.class,
|
||||
EppTlsModule.class,
|
||||
RdapModule.class,
|
||||
RequestModule.class,
|
||||
WhiteboxModule.class
|
||||
})
|
||||
public interface PubApiRequestComponent {
|
||||
CheckApiAction checkApiAction();
|
||||
RdapAutnumAction rdapAutnumAction();
|
||||
RdapDomainAction rdapDomainAction();
|
||||
RdapDomainSearchAction rdapDomainSearchAction();
|
||||
RdapEmptyAction rdapEmptyAction();
|
||||
RdapEntityAction rdapEntityAction();
|
||||
RdapEntitySearchAction rdapEntitySearchAction();
|
||||
RdapHelpAction rdapHelpAction();
|
||||
RdapIpAction rdapDefaultAction();
|
||||
RdapNameserverAction rdapNameserverAction();
|
||||
RdapNameserverSearchAction rdapNameserverSearchAction();
|
||||
|
||||
ReadinessProbeActionPubApi readinessProbeActionPubApi();
|
||||
|
||||
@Subcomponent.Builder
|
||||
abstract class Builder implements RequestComponentBuilder<PubApiRequestComponent> {
|
||||
@Override public abstract Builder requestModule(RequestModule requestModule);
|
||||
@Override public abstract PubApiRequestComponent build();
|
||||
}
|
||||
|
||||
@Module(subcomponents = PubApiRequestComponent.class)
|
||||
class PubApiRequestComponentModule {}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
// Copyright 2018 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.module.pubapi;
|
||||
|
||||
import google.registry.request.RequestHandler;
|
||||
import google.registry.request.auth.RequestAuthenticator;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Provider;
|
||||
|
||||
/** Request handler for the frontend module. */
|
||||
public class PubApiRequestHandler extends RequestHandler<PubApiRequestComponent> {
|
||||
|
||||
@Inject
|
||||
PubApiRequestHandler(
|
||||
Provider<PubApiRequestComponent.Builder> componentBuilderProvider,
|
||||
RequestAuthenticator requestAuthenticator) {
|
||||
super(componentBuilderProvider, requestAuthenticator);
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
// Copyright 2018 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.module.pubapi;
|
||||
|
||||
import com.google.monitoring.metrics.MetricReporter;
|
||||
import dagger.Lazy;
|
||||
import google.registry.module.ServletBase;
|
||||
|
||||
/** Servlet that should handle all requests to our "default" App Engine module. */
|
||||
public final class PubApiServlet extends ServletBase {
|
||||
|
||||
private static final PubApiComponent component = DaggerPubApiComponent.create();
|
||||
private static final PubApiRequestHandler requestHandler = component.requestHandler();
|
||||
private static final Lazy<MetricReporter> metricReporter = component.metricReporter();
|
||||
|
||||
public PubApiServlet() {
|
||||
super(requestHandler, metricReporter);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
@javax.annotation.ParametersAreNonnullByDefault
|
||||
package google.registry.module.pubapi;
|
||||
@@ -1,69 +0,0 @@
|
||||
// Copyright 2017 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.module.tools;
|
||||
|
||||
import com.google.monitoring.metrics.MetricReporter;
|
||||
import dagger.Component;
|
||||
import dagger.Lazy;
|
||||
import google.registry.config.CloudTasksUtilsModule;
|
||||
import google.registry.config.CredentialModule;
|
||||
import google.registry.config.RegistryConfig.ConfigModule;
|
||||
import google.registry.export.DriveModule;
|
||||
import google.registry.flows.ServerTridProviderModule;
|
||||
import google.registry.flows.custom.CustomLogicFactoryModule;
|
||||
import google.registry.flows.domain.DomainDeletionTimeCacheModule;
|
||||
import google.registry.groups.DirectoryModule;
|
||||
import google.registry.groups.GroupsModule;
|
||||
import google.registry.groups.GroupssettingsModule;
|
||||
import google.registry.keyring.KeyringModule;
|
||||
import google.registry.keyring.api.KeyModule;
|
||||
import google.registry.module.tools.ToolsRequestComponent.ToolsRequestComponentModule;
|
||||
import google.registry.monitoring.whitebox.StackdriverModule;
|
||||
import google.registry.privileges.secretmanager.SecretManagerModule;
|
||||
import google.registry.request.Modules.GsonModule;
|
||||
import google.registry.request.Modules.NetHttpTransportModule;
|
||||
import google.registry.request.auth.AuthModule;
|
||||
import google.registry.util.UtilsModule;
|
||||
import jakarta.inject.Singleton;
|
||||
|
||||
/** Dagger component with instance lifetime for "tools" App Engine module. */
|
||||
@Singleton
|
||||
@Component(
|
||||
modules = {
|
||||
AuthModule.class,
|
||||
ConfigModule.class,
|
||||
CredentialModule.class,
|
||||
CustomLogicFactoryModule.class,
|
||||
CloudTasksUtilsModule.class,
|
||||
DirectoryModule.class,
|
||||
DomainDeletionTimeCacheModule.class,
|
||||
DriveModule.class,
|
||||
GroupsModule.class,
|
||||
GroupssettingsModule.class,
|
||||
GsonModule.class,
|
||||
KeyModule.class,
|
||||
KeyringModule.class,
|
||||
NetHttpTransportModule.class,
|
||||
SecretManagerModule.class,
|
||||
ServerTridProviderModule.class,
|
||||
StackdriverModule.class,
|
||||
ToolsRequestComponentModule.class,
|
||||
UtilsModule.class
|
||||
})
|
||||
interface ToolsComponent {
|
||||
ToolsRequestHandler requestHandler();
|
||||
|
||||
Lazy<MetricReporter> metricReporter();
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
// Copyright 2017 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.module.tools;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Subcomponent;
|
||||
import google.registry.dns.DnsModule;
|
||||
import google.registry.flows.EppToolAction;
|
||||
import google.registry.flows.EppToolAction.EppToolModule;
|
||||
import google.registry.flows.FlowComponent;
|
||||
import google.registry.loadtest.LoadTestAction;
|
||||
import google.registry.loadtest.LoadTestModule;
|
||||
import google.registry.monitoring.whitebox.WhiteboxModule;
|
||||
import google.registry.request.RequestComponentBuilder;
|
||||
import google.registry.request.RequestModule;
|
||||
import google.registry.request.RequestScope;
|
||||
import google.registry.tools.server.CreateGroupsAction;
|
||||
import google.registry.tools.server.GenerateZoneFilesAction;
|
||||
import google.registry.tools.server.ListDomainsAction;
|
||||
import google.registry.tools.server.ListHostsAction;
|
||||
import google.registry.tools.server.ListPremiumListsAction;
|
||||
import google.registry.tools.server.ListRegistrarsAction;
|
||||
import google.registry.tools.server.ListReservedListsAction;
|
||||
import google.registry.tools.server.ListTldsAction;
|
||||
import google.registry.tools.server.RefreshDnsForAllDomainsAction;
|
||||
import google.registry.tools.server.ToolsServerModule;
|
||||
import google.registry.tools.server.UpdateUserGroupAction;
|
||||
import google.registry.tools.server.VerifyOteAction;
|
||||
|
||||
/** Dagger component with per-request lifetime for "tools" App Engine module. */
|
||||
@RequestScope
|
||||
@Subcomponent(
|
||||
modules = {
|
||||
DnsModule.class,
|
||||
EppToolModule.class,
|
||||
LoadTestModule.class,
|
||||
RequestModule.class,
|
||||
ToolsServerModule.class,
|
||||
WhiteboxModule.class,
|
||||
})
|
||||
public interface ToolsRequestComponent {
|
||||
FlowComponent.Builder flowComponentBuilder();
|
||||
|
||||
CreateGroupsAction createGroupsAction();
|
||||
EppToolAction eppToolAction();
|
||||
GenerateZoneFilesAction generateZoneFilesAction();
|
||||
ListDomainsAction listDomainsAction();
|
||||
ListHostsAction listHostsAction();
|
||||
ListPremiumListsAction listPremiumListsAction();
|
||||
ListRegistrarsAction listRegistrarsAction();
|
||||
ListReservedListsAction listReservedListsAction();
|
||||
ListTldsAction listTldsAction();
|
||||
LoadTestAction loadTestAction();
|
||||
RefreshDnsForAllDomainsAction refreshDnsForAllDomainsAction();
|
||||
|
||||
UpdateUserGroupAction updateUserGroupAction();
|
||||
|
||||
VerifyOteAction verifyOteAction();
|
||||
|
||||
@Subcomponent.Builder
|
||||
abstract class Builder implements RequestComponentBuilder<ToolsRequestComponent> {
|
||||
@Override public abstract Builder requestModule(RequestModule requestModule);
|
||||
@Override public abstract ToolsRequestComponent build();
|
||||
}
|
||||
|
||||
@Module(subcomponents = ToolsRequestComponent.class)
|
||||
class ToolsRequestComponentModule {}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
// Copyright 2017 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.module.tools;
|
||||
|
||||
import google.registry.request.RequestHandler;
|
||||
import google.registry.request.auth.RequestAuthenticator;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Provider;
|
||||
|
||||
/** Request handler for the tools module. */
|
||||
public class ToolsRequestHandler extends RequestHandler<ToolsRequestComponent> {
|
||||
|
||||
@Inject ToolsRequestHandler(
|
||||
Provider<ToolsRequestComponent.Builder> componentBuilderProvider,
|
||||
RequestAuthenticator requestAuthenticator) {
|
||||
super(componentBuilderProvider, requestAuthenticator);
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
// Copyright 2017 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.module.tools;
|
||||
|
||||
import com.google.monitoring.metrics.MetricReporter;
|
||||
import dagger.Lazy;
|
||||
import google.registry.module.ServletBase;
|
||||
|
||||
/** Servlet that should handle all requests to our "tools" App Engine module. */
|
||||
public final class ToolsServlet extends ServletBase {
|
||||
|
||||
private static final ToolsComponent component = DaggerToolsComponent.create();
|
||||
private static final ToolsRequestHandler requestHandler = component.requestHandler();
|
||||
private static final Lazy<MetricReporter> metricReporter = component.metricReporter();
|
||||
|
||||
public ToolsServlet() {
|
||||
super(requestHandler, metricReporter);
|
||||
}
|
||||
}
|
||||
@@ -658,7 +658,7 @@ public class RdapJsonFormatter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the list of RDAP roles for a registrar POC, using the visibleInWhoisAs* flags.
|
||||
* Creates the list of RDAP roles for a registrar POC, using the visibleInRdapAs* flags.
|
||||
*
|
||||
* <p>Only POCs with a non-empty role list should be visible.
|
||||
*
|
||||
@@ -672,13 +672,13 @@ public class RdapJsonFormatter {
|
||||
*/
|
||||
private static ImmutableList<RdapEntity.Role> makeRdapRoleList(RegistrarPoc registrarPoc) {
|
||||
ImmutableList.Builder<RdapEntity.Role> rolesBuilder = new ImmutableList.Builder<>();
|
||||
if (registrarPoc.getVisibleInWhoisAsAdmin()) {
|
||||
if (registrarPoc.getVisibleInRdapAsAdmin()) {
|
||||
rolesBuilder.add(RdapEntity.Role.ADMIN);
|
||||
}
|
||||
if (registrarPoc.getVisibleInWhoisAsTech()) {
|
||||
if (registrarPoc.getVisibleInRdapAsTech()) {
|
||||
rolesBuilder.add(RdapEntity.Role.TECH);
|
||||
}
|
||||
if (registrarPoc.getVisibleInDomainWhoisAsAbuse()) {
|
||||
if (registrarPoc.getVisibleInDomainRdapAsAbuse()) {
|
||||
rolesBuilder.add(RdapEntity.Role.ABUSE);
|
||||
}
|
||||
return rolesBuilder.build();
|
||||
|
||||
@@ -226,7 +226,7 @@ public class Spec11EmailUtils {
|
||||
|
||||
private InternetAddress getEmailAddressForRegistrar(String registrarId)
|
||||
throws MessagingException {
|
||||
// Attempt to use the registrar's WHOIS abuse contact, then fall back to the regular address.
|
||||
// Attempt to use the registrar's RDAP abuse contact, then fall back to the regular address.
|
||||
Registrar registrar =
|
||||
Registrar.loadByRegistrarIdCached(registrarId)
|
||||
.orElseThrow(
|
||||
@@ -235,7 +235,7 @@ public class Spec11EmailUtils {
|
||||
String.format("Could not find registrar %s", registrarId)));
|
||||
return new InternetAddress(
|
||||
registrar
|
||||
.getWhoisAbuseContact()
|
||||
.getRdapAbuseContact()
|
||||
.map(RegistrarPoc::getEmailAddress)
|
||||
.orElse(registrar.getEmailAddress()));
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ final class CreateRegistrarCommand extends CreateOrUpdateRegistrarCommand
|
||||
"Cannot add allowed TLDs when creating a REAL registrar in a production environment."
|
||||
+ " Please create the registrar without allowed TLDs, then use `nomulus"
|
||||
+ " registrar_contact` to create a registrar contact for it that is visible as the"
|
||||
+ " abuse contact in WHOIS. Then use `nomulus update_registrar` to add the allowed"
|
||||
+ " abuse contact in RDAP. Then use `nomulus update_registrar` to add the allowed"
|
||||
+ " TLDs.");
|
||||
}
|
||||
|
||||
|
||||
@@ -103,28 +103,27 @@ final class RegistrarPocCommand extends MutatingCommand {
|
||||
|
||||
@Nullable
|
||||
@Parameter(
|
||||
names = "--visible_in_whois_as_admin",
|
||||
description = " Whether this contact is publicly visible in WHOIS results as an "
|
||||
+ "Admin contact.",
|
||||
names = "--visible_in_rdap_as_admin",
|
||||
description = "If this contact is publicly visible in RDAP results as an " + "Admin contact.",
|
||||
arity = 1)
|
||||
private Boolean visibleInWhoisAsAdmin;
|
||||
private Boolean visibleInRdapAsAdmin;
|
||||
|
||||
@Nullable
|
||||
@Parameter(
|
||||
names = "--visible_in_whois_as_tech",
|
||||
description = " Whether this contact is publicly visible in WHOIS results as a "
|
||||
+ "Tech contact.",
|
||||
names = "--visible_in_rdap_as_tech",
|
||||
description = "If this contact is publicly visible in RDAP results as a " + "Tech contact.",
|
||||
arity = 1)
|
||||
private Boolean visibleInWhoisAsTech;
|
||||
private Boolean visibleInRdapAsTech;
|
||||
|
||||
@Nullable
|
||||
@Parameter(
|
||||
names = "--visible_in_domain_whois_as_abuse",
|
||||
description = " Whether this contact is publicly visible in WHOIS domain results as the "
|
||||
+ "registry abuse phone and email. If this flag is set, it will be cleared from all "
|
||||
+ "other contacts for the same registrar.",
|
||||
names = "--visible_in_domain_rdap_as_abuse",
|
||||
description =
|
||||
" Whether this contact is publicly visible in RDAP domain results as the "
|
||||
+ "registry abuse phone and email. If this flag is set, it will be cleared from all "
|
||||
+ "other contacts for the same registrar.",
|
||||
arity = 1)
|
||||
private Boolean visibleInDomainWhoisAsAbuse;
|
||||
private Boolean visibleInDomainRdapAsAbuse;
|
||||
|
||||
@Parameter(
|
||||
names = {"-o", "--output"},
|
||||
@@ -166,8 +165,8 @@ final class RegistrarPocCommand extends MutatingCommand {
|
||||
case LIST -> listContacts(contacts);
|
||||
case CREATE -> {
|
||||
stageEntityChange(null, createContact(registrar));
|
||||
if (visibleInDomainWhoisAsAbuse != null && visibleInDomainWhoisAsAbuse) {
|
||||
unsetOtherWhoisAbuseFlags(contacts, null);
|
||||
if (visibleInDomainRdapAsAbuse != null && visibleInDomainRdapAsAbuse) {
|
||||
unsetOtherRdapAbuseFlags(contacts, null);
|
||||
}
|
||||
}
|
||||
case UPDATE -> {
|
||||
@@ -178,13 +177,13 @@ final class RegistrarPocCommand extends MutatingCommand {
|
||||
email);
|
||||
RegistrarPoc newContact = updateContact(oldContact, registrar);
|
||||
checkArgument(
|
||||
!oldContact.getVisibleInDomainWhoisAsAbuse()
|
||||
|| newContact.getVisibleInDomainWhoisAsAbuse(),
|
||||
"Cannot clear visible_in_domain_whois_as_abuse flag, as that would leave no domain"
|
||||
+ " WHOIS abuse contacts; instead, set the flag on another contact");
|
||||
!oldContact.getVisibleInDomainRdapAsAbuse()
|
||||
|| newContact.getVisibleInDomainRdapAsAbuse(),
|
||||
"Cannot clear visible_in_domain_rdap_as_abuse flag, as that would leave no domain"
|
||||
+ " RDAP abuse contacts; instead, set the flag on another contact");
|
||||
stageEntityChange(oldContact, newContact);
|
||||
if (visibleInDomainWhoisAsAbuse != null && visibleInDomainWhoisAsAbuse) {
|
||||
unsetOtherWhoisAbuseFlags(contacts, oldContact.getEmailAddress());
|
||||
if (visibleInDomainRdapAsAbuse != null && visibleInDomainRdapAsAbuse) {
|
||||
unsetOtherRdapAbuseFlags(contacts, oldContact.getEmailAddress());
|
||||
}
|
||||
}
|
||||
case DELETE -> {
|
||||
@@ -194,8 +193,8 @@ final class RegistrarPocCommand extends MutatingCommand {
|
||||
"No contact with the given email: %s",
|
||||
email);
|
||||
checkArgument(
|
||||
!oldContact.getVisibleInDomainWhoisAsAbuse(),
|
||||
"Cannot delete the domain WHOIS abuse contact; set the flag on another contact first");
|
||||
!oldContact.getVisibleInDomainRdapAsAbuse(),
|
||||
"Cannot delete the domain RDAP abuse contact; set the flag on another contact first");
|
||||
stageEntityChange(oldContact, null);
|
||||
}
|
||||
default -> throw new AssertionError();
|
||||
@@ -228,14 +227,14 @@ final class RegistrarPocCommand extends MutatingCommand {
|
||||
}
|
||||
builder.setTypes(nullToEmpty(contactTypes));
|
||||
|
||||
if (visibleInWhoisAsAdmin != null) {
|
||||
builder.setVisibleInWhoisAsAdmin(visibleInWhoisAsAdmin);
|
||||
if (visibleInRdapAsAdmin != null) {
|
||||
builder.setVisibleInRdapAsAdmin(visibleInRdapAsAdmin);
|
||||
}
|
||||
if (visibleInWhoisAsTech != null) {
|
||||
builder.setVisibleInWhoisAsTech(visibleInWhoisAsTech);
|
||||
if (visibleInRdapAsTech != null) {
|
||||
builder.setVisibleInRdapAsTech(visibleInRdapAsTech);
|
||||
}
|
||||
if (visibleInDomainWhoisAsAbuse != null) {
|
||||
builder.setVisibleInDomainWhoisAsAbuse(visibleInDomainWhoisAsAbuse);
|
||||
if (visibleInDomainRdapAsAbuse != null) {
|
||||
builder.setVisibleInDomainRdapAsAbuse(visibleInDomainRdapAsAbuse);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
@@ -257,24 +256,24 @@ final class RegistrarPocCommand extends MutatingCommand {
|
||||
if (contactTypes != null) {
|
||||
builder.setTypes(contactTypes);
|
||||
}
|
||||
if (visibleInWhoisAsAdmin != null) {
|
||||
builder.setVisibleInWhoisAsAdmin(visibleInWhoisAsAdmin);
|
||||
if (visibleInRdapAsAdmin != null) {
|
||||
builder.setVisibleInRdapAsAdmin(visibleInRdapAsAdmin);
|
||||
}
|
||||
if (visibleInWhoisAsTech != null) {
|
||||
builder.setVisibleInWhoisAsTech(visibleInWhoisAsTech);
|
||||
if (visibleInRdapAsTech != null) {
|
||||
builder.setVisibleInRdapAsTech(visibleInRdapAsTech);
|
||||
}
|
||||
if (visibleInDomainWhoisAsAbuse != null) {
|
||||
builder.setVisibleInDomainWhoisAsAbuse(visibleInDomainWhoisAsAbuse);
|
||||
if (visibleInDomainRdapAsAbuse != null) {
|
||||
builder.setVisibleInDomainRdapAsAbuse(visibleInDomainRdapAsAbuse);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private void unsetOtherWhoisAbuseFlags(
|
||||
private void unsetOtherRdapAbuseFlags(
|
||||
ImmutableSet<RegistrarPoc> contacts, @Nullable String emailAddressNotToChange) {
|
||||
for (RegistrarPoc contact : contacts) {
|
||||
if (!contact.getEmailAddress().equals(emailAddressNotToChange)
|
||||
&& contact.getVisibleInDomainWhoisAsAbuse()) {
|
||||
RegistrarPoc newContact = contact.asBuilder().setVisibleInDomainWhoisAsAbuse(false).build();
|
||||
&& contact.getVisibleInDomainRdapAsAbuse()) {
|
||||
RegistrarPoc newContact = contact.asBuilder().setVisibleInDomainRdapAsAbuse(false).build();
|
||||
stageEntityChange(contact, newContact);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ final class UpdateRegistrarCommand extends CreateOrUpdateRegistrarCommand {
|
||||
@Override
|
||||
void checkModifyAllowedTlds(@Nullable Registrar oldRegistrar) {
|
||||
// Only allow modifying allowed TLDs if we're in a non-PRODUCTION environment, if the registrar
|
||||
// is not REAL, or the registrar has a WHOIS abuse contact set.
|
||||
// is not REAL, or the registrar has an RDAP abuse contact set.
|
||||
checkArgumentNotNull(oldRegistrar, "Old registrar was not present during modification");
|
||||
|
||||
boolean isRealRegistrar =
|
||||
@@ -43,9 +43,9 @@ final class UpdateRegistrarCommand extends CreateOrUpdateRegistrarCommand {
|
||||
|| (Registrar.Type.REAL.equals(oldRegistrar.getType()) && registrarType == null);
|
||||
if (RegistryEnvironment.PRODUCTION.equals(RegistryEnvironment.get()) && isRealRegistrar) {
|
||||
checkArgumentPresent(
|
||||
oldRegistrar.getWhoisAbuseContact(),
|
||||
"Cannot modify allowed TLDs if there is no WHOIS abuse contact set. Please use the"
|
||||
+ " \"nomulus registrar_contact\" command on this registrar to set a WHOIS abuse"
|
||||
oldRegistrar.getRdapAbuseContact(),
|
||||
"Cannot modify allowed TLDs if there is no RDAP abuse contact set. Please use the"
|
||||
+ " \"nomulus registrar_contact\" command on this registrar to set an RDAP abuse"
|
||||
+ " contact.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
// Copyright 2017 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;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
/** Enum defining which JS/CSS files get rendered in a soy templates. */
|
||||
public enum ConsoleDebug {
|
||||
|
||||
/** Use compiled CSS and JS. */
|
||||
PRODUCTION,
|
||||
|
||||
/** Use debug compiled CSS and JS, where symbols are only <i>slightly</i> mangled. */
|
||||
DEBUG,
|
||||
|
||||
/**
|
||||
* Use debug compiled CSS and raw JS from internal source code dependency-managed directory
|
||||
* structure.
|
||||
*/
|
||||
RAW,
|
||||
|
||||
/** Don't use any CSS or JS. This is used by JSTD unit tests. */
|
||||
TEST;
|
||||
|
||||
private static final String PROPERTY = "console.debug";
|
||||
private static final String DEFAULT = PRODUCTION.name();
|
||||
|
||||
/** Returns value configured by system property {@code #PROPERTY}. */
|
||||
public static ConsoleDebug get() {
|
||||
return valueOf(System.getProperty(PROPERTY, DEFAULT));
|
||||
}
|
||||
|
||||
/** Sets the global {@link ConsoleDebug} state. */
|
||||
public static void set(ConsoleDebug value) {
|
||||
System.setProperty(PROPERTY, value.toString());
|
||||
}
|
||||
|
||||
/** Dagger module for ConsoleDebug. */
|
||||
@Module
|
||||
public static final class ConsoleConfigModule {
|
||||
|
||||
@Provides
|
||||
static ConsoleDebug provideConsoleDebug() {
|
||||
return ConsoleDebug.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
// Copyright 2017 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.forms;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import javax.annotation.Detainted;
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
/**
|
||||
* Exception thrown when a form is invalid. Problems with a specific
|
||||
* form field should use {@link FormFieldException} instead.
|
||||
*
|
||||
* <p>You can safely throw {@code FormException} from within your form
|
||||
* validator, and the message will automatically be propagated to the
|
||||
* client form interface.
|
||||
*/
|
||||
@NotThreadSafe
|
||||
public class FormException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Creates a new {@link FormException}
|
||||
*
|
||||
* @param userMessage should be a friendly message that's safe to show to the user.
|
||||
*/
|
||||
public FormException(@Detainted String userMessage) {
|
||||
super(checkNotNull(userMessage, "userMessage"), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link FormException}
|
||||
*
|
||||
* @param userMessage should be a friendly message that's safe to show to the user.
|
||||
* @param cause the original cause of this exception. May be null.
|
||||
*/
|
||||
public FormException(@Detainted String userMessage, Throwable cause) {
|
||||
super(checkNotNull(userMessage, "userMessage"), cause);
|
||||
}
|
||||
|
||||
/** Returns an error message that's safe to display to the user. */
|
||||
@Override
|
||||
@Detainted
|
||||
public String getMessage() {
|
||||
return super.getMessage();
|
||||
}
|
||||
}
|
||||
@@ -1,762 +0,0 @@
|
||||
// Copyright 2017 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.forms;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
|
||||
import com.google.common.base.Ascii;
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Range;
|
||||
import com.google.common.collect.Streams;
|
||||
import com.google.re2j.Pattern;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import javax.annotation.Detainted;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.Tainted;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
/**
|
||||
* Declarative functional fluent form field converter / validator.
|
||||
*
|
||||
* <p>This class is responsible for converting arbitrary data, sent to us by the web browser, into
|
||||
* validated data structures that the server-side code can use. For example:
|
||||
*
|
||||
* <pre>{@code
|
||||
* private enum Gender { MALE, FEMALE }
|
||||
*
|
||||
* private static final FormField<String, String> NAME_FIELD = FormField.named("name")
|
||||
* .matches("[a-z]+")
|
||||
* .range(atMost(16))
|
||||
* .required()
|
||||
* .build();
|
||||
*
|
||||
* private static final FormField<String, Gender> GENDER_FIELD = FormField.named("gender")
|
||||
* .asEnum(Gender.class)
|
||||
* .required()
|
||||
* .build();
|
||||
*
|
||||
* public Person makePerson(Map<String, String> params) {
|
||||
* Person.Builder person = new Person.Builder();
|
||||
* for (String name : NAME_FIELD.extract(params).asSet()) {
|
||||
* person.setName(name);
|
||||
* }
|
||||
* for (Gender name : GENDER_FIELD.extract(params).asSet()) {
|
||||
* person.setGender(name);
|
||||
* }
|
||||
* return person.build();
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>This class provides <b>full type-safety</b> <i>if and only if</i> you statically initialize
|
||||
* your FormField objects and write a unit test that causes the class to be loaded.
|
||||
*
|
||||
* <h2>Exception Handling</h2>
|
||||
*
|
||||
* <p>When values passed to {@link #convert} or {@link #extract} don't meet the contract, {@link
|
||||
* FormFieldException} will be thrown, which provides the field name and a short error message
|
||||
* that's safe to pass along to the client.
|
||||
*
|
||||
* <p>You can safely throw {@code FormFieldException} from within your validator functions, and the
|
||||
* field name will automatically be propagated into the exception object for you.
|
||||
*
|
||||
* <p>In situations when you're validating lists or maps, you'll end up with a hierarchical field
|
||||
* naming structure. For example, if you were validating a list of maps, an error generated by the
|
||||
* {@code bar} field of the fifth item in the {@code foo} field would have a fully-qualified field
|
||||
* name of: {@code foo[5][bar]}.
|
||||
*
|
||||
* <h3>Library Definitions</h3>
|
||||
*
|
||||
* <p>You should never assign a partially constructed {@code FormField.Builder} to a variable or
|
||||
* constant. Instead, you should use {@link #asBuilder()} or {@link #asBuilderNamed(String)}.
|
||||
*
|
||||
* <p>Here is an example of how you might go about defining library definitions:
|
||||
*
|
||||
* <pre>{@code
|
||||
* final class FormFields {
|
||||
* private static final FormField<String, String> COUNTRY_CODE =
|
||||
* FormField.named("countryCode")
|
||||
* .range(Range.singleton(2))
|
||||
* .uppercased()
|
||||
* .in(ImmutableSet.copyOf(Locale.getISOCountries()))
|
||||
* .build();
|
||||
* }
|
||||
*
|
||||
* final class Form {
|
||||
* private static final FormField<String, String> COUNTRY_CODE_FIELD =
|
||||
* FormFields.COUNTRY_CODE.asBuilder()
|
||||
* .required()
|
||||
* .build();
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* @param <I> input value type
|
||||
* @param <O> output value type
|
||||
*/
|
||||
@Immutable
|
||||
public final class FormField<I, O> {
|
||||
|
||||
private final String name;
|
||||
private final Class<I> typeIn;
|
||||
private final Class<O> typeOut;
|
||||
private final Function<I, O> converter;
|
||||
|
||||
private FormField(String name, Class<I> typeIn, Class<O> typeOut, Function<I, O> converter) {
|
||||
this.name = name;
|
||||
this.typeIn = typeIn;
|
||||
this.typeOut = typeOut;
|
||||
this.converter = converter;
|
||||
}
|
||||
|
||||
/** Returns an optional string form field named {@code name}. */
|
||||
public static Builder<String, String> named(String name) {
|
||||
return named(name, String.class);
|
||||
}
|
||||
|
||||
/** Returns an optional form field named {@code name} with a specific {@code inputType}. */
|
||||
public static <T> Builder<T, T> named(String name, Class<T> typeIn) {
|
||||
checkArgument(!name.isEmpty());
|
||||
return new Builder<>(name, checkNotNull(typeIn), typeIn, x -> x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a form field builder for validating JSON nested maps.
|
||||
*
|
||||
* <p>Here's an example of how you'd use this feature:
|
||||
*
|
||||
* <pre>
|
||||
* private static final FormField<String, String> REGISTRAR_NAME_FIELD =
|
||||
* FormField.named("name")
|
||||
* .emptyToNull()
|
||||
* .required()
|
||||
* .build();
|
||||
*
|
||||
* private static final FormField<Map<String, ?>, Registrar> REGISTRAR_FIELD =
|
||||
* FormField.mapNamed("registrar")
|
||||
* .transform(Registrar.class, new Function<Map<String, ?>, Registrar>() {
|
||||
* @Nullable
|
||||
* @Override
|
||||
* public Registrar apply(@Nullable Map<String, ?> params) {
|
||||
* Registrar.Builder builder = new Registrar.Builder();
|
||||
* for (String name : REGISTRAR_NAME_FIELD.extractUntyped(params).asSet()) {
|
||||
* builder.setName(name);
|
||||
* }
|
||||
* return builder.build();
|
||||
* }})
|
||||
* .build();</pre>
|
||||
*
|
||||
* <p>When a {@link FormFieldException} is thrown, it'll be propagated to create a fully-qualified
|
||||
* field name. For example, if the JSON input is <pre>{registrar: {name: ""}}</pre> then the
|
||||
* {@link FormFieldException#getFieldName() field name} will be {@code registrar.name}.
|
||||
*/
|
||||
public static Builder<Map<String, ?>, Map<String, ?>> mapNamed(String name) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<Map<String, ?>> typeIn = (Class<Map<String, ?>>) (Class<?>) Map.class;
|
||||
return named(name, typeIn);
|
||||
}
|
||||
|
||||
/** Returns the name of this field. */
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert and validate a raw user-supplied value.
|
||||
*
|
||||
* @throws FormFieldException if value does not meet expected contracts.
|
||||
*/
|
||||
@Detainted
|
||||
public Optional<O> convert(@Tainted @Nullable I value) {
|
||||
try {
|
||||
return Optional.ofNullable(converter.apply(value));
|
||||
} catch (FormFieldException e) {
|
||||
throw e.propagate(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert and validate a raw user-supplied value from a map.
|
||||
*
|
||||
* <p>This is the same as saying: {@code field.convert(valueMap.get(field.name())}
|
||||
*
|
||||
* @throws FormFieldException if value does not meet expected contracts.
|
||||
*/
|
||||
@Detainted
|
||||
public Optional<O> extract(@Tainted Map<String, I> valueMap) {
|
||||
return convert(valueMap.get(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert and validate a raw user-supplied value from an untyped JSON map.
|
||||
*
|
||||
* @throws FormFieldException if value is wrong type or does not meet expected contracts.
|
||||
*/
|
||||
@Detainted
|
||||
public Optional<O> extractUntyped(@Tainted Map<String, ?> jsonMap) {
|
||||
Object value = jsonMap.get(name);
|
||||
I castedValue;
|
||||
try {
|
||||
castedValue = typeIn.cast(value);
|
||||
} catch (ClassCastException e) {
|
||||
throw new FormFieldException(String.format("Type error: got: %s, expected: %s",
|
||||
value.getClass().getSimpleName(),
|
||||
typeIn.getSimpleName())).propagate(name);
|
||||
}
|
||||
return convert(castedValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a builder of this object, which can be used to further restrict validation.
|
||||
*
|
||||
* @see #asBuilderNamed(String)
|
||||
*/
|
||||
public Builder<I, O> asBuilder() {
|
||||
return new Builder<>(name, typeIn, typeOut, converter);
|
||||
}
|
||||
|
||||
/** Same as {@link #asBuilder()} but changes the field name. */
|
||||
public Builder<I, O> asBuilderNamed(String newName) {
|
||||
checkArgument(!newName.isEmpty());
|
||||
return new Builder<>(newName, typeIn, typeOut, converter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutable builder for {@link FormField}.
|
||||
*
|
||||
* @param <I> input value type
|
||||
* @param <O> output value type
|
||||
*/
|
||||
public static final class Builder<I, O> {
|
||||
private final String name;
|
||||
private final Class<I> typeIn;
|
||||
private final Class<O> typeOut;
|
||||
private Function<I, O> converter;
|
||||
|
||||
private Builder(String name, Class<I> typeIn, Class<O> typeOut, Function<I, O> converter) {
|
||||
this.name = name;
|
||||
this.typeIn = typeIn;
|
||||
this.typeOut = typeOut;
|
||||
this.converter = converter;
|
||||
}
|
||||
|
||||
/** Causes {@code defaultValue} to be substituted if value is {@code null}. */
|
||||
public Builder<I, O> withDefault(O defaultValue) {
|
||||
return transform(new DefaultFunction<>(checkNotNull(defaultValue)));
|
||||
}
|
||||
|
||||
/** Ensure value is not {@code null}. */
|
||||
public Builder<I, O> required() {
|
||||
return transform(Builder::checkNotNullTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform empty values into {@code null}.
|
||||
*
|
||||
* @throws IllegalStateException if current output type is not a {@link CharSequence} or
|
||||
* {@link Collection}.
|
||||
*/
|
||||
public Builder<I, O> emptyToNull() {
|
||||
checkState(CharSequence.class.isAssignableFrom(typeOut)
|
||||
|| Collection.class.isAssignableFrom(typeOut));
|
||||
return transform(
|
||||
input ->
|
||||
((input instanceof CharSequence) && (((CharSequence) input).length() == 0))
|
||||
|| ((input instanceof Collection) && ((Collection<?>) input).isEmpty())
|
||||
? null
|
||||
: input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify {@link String} input to remove whitespace around the sides.
|
||||
*
|
||||
* <p>{@code null} values are passed through.
|
||||
*
|
||||
* @throws IllegalStateException if current output type is not a String.
|
||||
*/
|
||||
public Builder<I, String> trimmed() {
|
||||
checkState(String.class.isAssignableFrom(typeOut));
|
||||
@SuppressWarnings("unchecked")
|
||||
Function<O, String> trimFunction =
|
||||
(Function<O, String>)
|
||||
((Function<String, String>) input -> input != null ? input.trim() : null);
|
||||
return transform(String.class, trimFunction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify {@link String} input to be uppercase.
|
||||
*
|
||||
* <p>{@code null} values are passed through.
|
||||
*
|
||||
* @throws IllegalStateException if current output type is not a String.
|
||||
*/
|
||||
public Builder<I, String> uppercased() {
|
||||
checkState(String.class.isAssignableFrom(typeOut));
|
||||
@SuppressWarnings("unchecked")
|
||||
Function<O, String> funk =
|
||||
(Function<O, String>)
|
||||
((Function<String, String>)
|
||||
input -> input != null ? input.toUpperCase(Locale.ENGLISH) : null);
|
||||
return transform(String.class, funk);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify {@link String} input to be lowercase.
|
||||
*
|
||||
* <p>{@code null} values are passed through.
|
||||
*
|
||||
* @throws IllegalStateException if current output type is not a String.
|
||||
*/
|
||||
public Builder<I, String> lowercased() {
|
||||
checkState(String.class.isAssignableFrom(typeOut));
|
||||
@SuppressWarnings("unchecked")
|
||||
Function<O, String> funk =
|
||||
(Function<O, String>)
|
||||
((Function<String, String>)
|
||||
input -> input != null ? input.toLowerCase(Locale.ENGLISH) : null);
|
||||
return transform(String.class, funk);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure input matches {@code pattern}.
|
||||
*
|
||||
* <p>{@code null} values are passed through.
|
||||
*
|
||||
* @param pattern is used to validate the user input. It matches against the whole string, so
|
||||
* you don't need to use the ^$ characters.
|
||||
* @param errorMessage is a helpful error message, which should include an example. If this is
|
||||
* not provided, a default error message will be shown that includes the regexp pattern.
|
||||
* @throws IllegalStateException if current output type is not a {@link CharSequence}.
|
||||
* @see #matches(Pattern)
|
||||
*/
|
||||
public Builder<I, O> matches(Pattern pattern, @Nullable String errorMessage) {
|
||||
checkState(CharSequence.class.isAssignableFrom(typeOut));
|
||||
return transform(
|
||||
new MatchesFunction<>(checkNotNull(pattern), Optional.ofNullable(errorMessage)));
|
||||
}
|
||||
|
||||
/** Alias for {@link #matches(Pattern, String) matches(pattern, null)} */
|
||||
public Builder<I, O> matches(Pattern pattern) {
|
||||
return matches(pattern, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all characters not in {@code matcher}.
|
||||
*
|
||||
* <p>{@code null} values are passed through.
|
||||
*
|
||||
* @param matcher indicates which characters are to be retained
|
||||
* @throws IllegalStateException if current output type is not a {@link CharSequence}
|
||||
*/
|
||||
public Builder<I, String> retains(CharMatcher matcher) {
|
||||
checkState(CharSequence.class.isAssignableFrom(typeOut));
|
||||
@SuppressWarnings("unchecked") // safe due to checkState call
|
||||
Function<O, String> function =
|
||||
(Function<O, String>) new RetainFunction(checkNotNull(matcher));
|
||||
return transform(String.class, function);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforce value length/size/value is within {@code range}.
|
||||
*
|
||||
* <p>The following input value types are supported:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link CharSequence}: Length must be within {@code range}.
|
||||
* <li>{@link Collection}: Size must be within {@code range}.
|
||||
* <li>{@link Number}: Value must be within {@code range}.
|
||||
* </ul>
|
||||
*
|
||||
* <p>{@code null} values are passed through. Please note that setting a lower bound on your
|
||||
* range does not imply {@link #required()}, as range checking only applies to non-{@code null}
|
||||
* values.
|
||||
*
|
||||
* @throws IllegalStateException if current output type is not one of the above types.
|
||||
*/
|
||||
public Builder<I, O> range(Range<Integer> range) {
|
||||
checkState(CharSequence.class.isAssignableFrom(typeOut)
|
||||
|| Collection.class.isAssignableFrom(typeOut)
|
||||
|| Number.class.isAssignableFrom(typeOut));
|
||||
return transform(new RangeFunction<>(checkNotNull(range)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforce value be a member of {@code values}.
|
||||
*
|
||||
* <p>{@code null} values are passed through.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code values} is empty.
|
||||
*/
|
||||
public Builder<I, O> in(Set<O> values) {
|
||||
checkArgument(!values.isEmpty());
|
||||
return transform(new InFunction<>(values));
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs arbitrary type transformation from {@code O} to {@code T}.
|
||||
*
|
||||
* <p>Your {@code transform} function is expected to pass-through {@code null} values as a
|
||||
* no-op, since it's up to {@link #required()} to block them. You might also want to consider
|
||||
* using a try block that rethrows exceptions as {@link FormFieldException}.
|
||||
*
|
||||
* <p>Here's an example of how you'd convert from String to Integer:
|
||||
*
|
||||
* <pre>
|
||||
* FormField.named("foo", String.class)
|
||||
* .transform(Integer.class, new Function<String, Integer>() {
|
||||
* @Nullable
|
||||
* @Override
|
||||
* public Integer apply(@Nullable String input) {
|
||||
* try {
|
||||
* return input != null ? Integer.parseInt(input) : null;
|
||||
* } catch (IllegalArgumentException e) {
|
||||
* throw new FormFieldException("Invalid number.", e);
|
||||
* }
|
||||
* }})
|
||||
* .build();</pre>
|
||||
*
|
||||
* @see #transform(Function)
|
||||
*/
|
||||
public <T> Builder<I, T> transform(Class<T> newType, Function<O, T> transform) {
|
||||
return new Builder<>(
|
||||
name, typeIn, checkNotNull(newType), this.converter.andThen(checkNotNull(transform)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Manipulates values without changing type.
|
||||
*
|
||||
* <p>Please see {@link #transform(Class, Function)} for information about the contract to
|
||||
* which {@code transform} is expected to conform.
|
||||
*/
|
||||
public Builder<I, O> transform(Function<O, O> transform) {
|
||||
this.converter = this.converter.andThen(checkNotNull(transform));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uppercases value and converts to an enum field of {@code enumClass}.
|
||||
*
|
||||
* <p>{@code null} values are passed through.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code enumClass} is not an enum class.
|
||||
* @throws IllegalStateException if current output type is not a String.
|
||||
*/
|
||||
public <C extends Enum<C>> Builder<I, C> asEnum(Class<C> enumClass) {
|
||||
checkArgument(enumClass.isEnum());
|
||||
checkState(String.class.isAssignableFrom(typeOut));
|
||||
return transform(enumClass, new ToEnumFunction<>(enumClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns this form field into something that processes lists.
|
||||
*
|
||||
* <p>The current object definition will be applied to each item in the list. If a
|
||||
* {@link FormFieldException} is thrown when processing an item, then its
|
||||
* {@link FormFieldException#getFieldName() fieldName} will be rewritten to include the index,
|
||||
* e.g. {@code name} becomes {@code name[0]}.
|
||||
*
|
||||
* <p>The outputted list will be an {@link ImmutableList}. This is not reflected in the generic
|
||||
* typing for the sake of brevity.
|
||||
*
|
||||
* <p>A {@code null} value for list will be passed through. List items that convert to
|
||||
* {@code null} will be discarded (since {@code ImmutableList} does not permit {@code null}
|
||||
* values).
|
||||
*/
|
||||
public Builder<List<I>, List<O>> asList() {
|
||||
@SuppressWarnings("unchecked") Class<List<I>> in = (Class<List<I>>) (Class<I>) List.class;
|
||||
@SuppressWarnings("unchecked") Class<List<O>> out = (Class<List<O>>) (Class<O>) List.class;
|
||||
return new Builder<>(name, in, out, new ToListFunction<>(build()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns this form field into a split string list that applies itself to each item.
|
||||
*
|
||||
* <p>The behavior of this method is counter-intuitive. It behaves similar to {@link #asList()}
|
||||
* in the sense that all transforms specified <i>before</i> this method will be applied to the
|
||||
* individual resulting list items.
|
||||
*
|
||||
* <p>For example, to turn a comma-delimited string into an enum list:<pre> {@code
|
||||
*
|
||||
* private static final FormField<String, List<State>> STATES_FIELD =
|
||||
* FormField.named("states")
|
||||
* .uppercased()
|
||||
* .asEnum(State.class)
|
||||
* .asList(Splitter.on(',').omitEmptyStrings().trimResults())
|
||||
* .build();}</pre>
|
||||
*
|
||||
* <p>You'll notice that the transforms specified before this method are applied to each list
|
||||
* item. However unlike {@link #asList()}, if an error is thrown on an individual item, then
|
||||
* {@link FormFieldException#getFieldName()} will <i>not</i> contain the index.
|
||||
*
|
||||
* @throws IllegalStateException If either the current input type isn't String.
|
||||
*/
|
||||
public Builder<String, List<O>> asList(Splitter splitter) {
|
||||
checkNotNull(splitter);
|
||||
checkState(String.class.isAssignableFrom(typeIn));
|
||||
@SuppressWarnings("unchecked") Class<List<O>> out = (Class<List<O>>) (Class<O>) List.class;
|
||||
@SuppressWarnings("unchecked") FormField<String, O> inField = (FormField<String, O>) build();
|
||||
return new Builder<>(name, String.class, out, new SplitToListFunction<>(inField, splitter));
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #asList()} but outputs an {@link ImmutableSet} instead.
|
||||
*
|
||||
* @throws IllegalStateException if you called asList() before calling this method.
|
||||
*/
|
||||
public Builder<List<I>, Set<O>> asSet() {
|
||||
checkState(!List.class.isAssignableFrom(typeOut));
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<Set<O>> setOut = (Class<Set<O>>) (Class<O>) Set.class;
|
||||
@SuppressWarnings("unchecked")
|
||||
Function<List<O>, Set<O>> toSetFunction =
|
||||
(Function<List<O>, Set<O>>)
|
||||
(Function<O, O>)
|
||||
((Function<List<Object>, Set<Object>>)
|
||||
input -> input != null ? ImmutableSet.copyOf(input) : null);
|
||||
return asList().transform(setOut, toSetFunction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #asList(Splitter)} but outputs an {@link ImmutableSet} instead.
|
||||
*
|
||||
* @throws IllegalStateException If the current input type isn't String.
|
||||
*/
|
||||
public Builder<String, Set<O>> asSet(Splitter splitter) {
|
||||
checkNotNull(splitter);
|
||||
checkState(String.class.isAssignableFrom(typeIn));
|
||||
@SuppressWarnings("unchecked") Class<Set<O>> out = (Class<Set<O>>) (Class<O>) Set.class;
|
||||
@SuppressWarnings("unchecked") FormField<String, O> inField = (FormField<String, O>) build();
|
||||
return new Builder<>(name, String.class, out, new SplitToSetFunction<>(inField, splitter));
|
||||
}
|
||||
|
||||
/** Creates a new {@link FormField} instance. */
|
||||
public FormField<I, O> build() {
|
||||
return new FormField<>(name, typeIn, typeOut, converter);
|
||||
}
|
||||
|
||||
private static <O> O checkNotNullTransform(@Nullable O input) {
|
||||
if (input == null) {
|
||||
throw new FormFieldException("This field is required.");
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
private static final class DefaultFunction<O> implements Function<O, O> {
|
||||
private final O defaultValue;
|
||||
|
||||
DefaultFunction(O defaultValue) {
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public O apply(@Nullable O input) {
|
||||
return input != null ? input : defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class RangeFunction<O> implements Function<O, O> {
|
||||
private final Range<Integer> range;
|
||||
|
||||
RangeFunction(Range<Integer> range) {
|
||||
this.range = range;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public O apply(@Nullable O input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
if (input instanceof CharSequence) {
|
||||
checkRangeContains(range, ((CharSequence) input).length(), "Number of characters");
|
||||
} else if (input instanceof Collection) {
|
||||
checkRangeContains(range, ((Collection<?>) input).size(), "Number of items");
|
||||
} else if (input instanceof Number) {
|
||||
checkRangeContains(range, ((Number) input).intValue(), "Value");
|
||||
} else {
|
||||
throw new AssertionError();
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
private void checkRangeContains(Range<Integer> range, int value, String message) {
|
||||
if (!range.contains(value)) {
|
||||
throw new FormFieldException(
|
||||
String.format("%s (%,d) not in range %s", message, value, range));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class InFunction<O> implements Function<O, O> {
|
||||
private final Set<O> values;
|
||||
|
||||
InFunction(Set<O> values) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public O apply(@Nullable O input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
if (!values.contains(input)) {
|
||||
throw new FormFieldException("Unrecognized value.");
|
||||
}
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class MatchesFunction<O> implements Function<O, O> {
|
||||
private final Pattern pattern;
|
||||
private final Optional<String> errorMessage;
|
||||
|
||||
MatchesFunction(Pattern pattern, Optional<String> errorMessage) {
|
||||
this.pattern = pattern;
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public O apply(@Nullable O input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
if (!pattern.matcher((CharSequence) input).matches()) {
|
||||
throw new FormFieldException(errorMessage.orElse("Must match pattern: " + pattern));
|
||||
}
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class RetainFunction implements Function<CharSequence, String> {
|
||||
private final CharMatcher matcher;
|
||||
|
||||
RetainFunction(CharMatcher matcher) {
|
||||
this.matcher = matcher;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String apply(@Nullable CharSequence input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
return matcher.retainFrom(input);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ToEnumFunction<O, C extends Enum<C>> implements Function<O, C> {
|
||||
private final Class<C> enumClass;
|
||||
|
||||
ToEnumFunction(Class<C> enumClass) {
|
||||
this.enumClass = enumClass;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public C apply(@Nullable O input) {
|
||||
try {
|
||||
return input != null ? Enum.valueOf(enumClass, Ascii.toUpperCase((String) input)) : null;
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new FormFieldException(
|
||||
String.format("Enum %s does not contain '%s'", enumClass.getSimpleName(), input));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ToListFunction<I, O> implements Function<List<I>, List<O>> {
|
||||
private final FormField<I, O> itemField;
|
||||
|
||||
ToListFunction(FormField<I, O> itemField) {
|
||||
this.itemField = itemField;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<O> apply(@Nullable List<I> input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
ImmutableList.Builder<O> builder = new ImmutableList.Builder<>();
|
||||
for (int i = 0; i < input.size(); i++) {
|
||||
I inputItem = itemField.typeIn.cast(input.get(i));
|
||||
O outputItem;
|
||||
try {
|
||||
outputItem = itemField.converter.apply(inputItem);
|
||||
} catch (FormFieldException e) {
|
||||
throw e.propagate(i);
|
||||
}
|
||||
if (outputItem != null) {
|
||||
builder.add(outputItem);
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SplitToListFunction<O> implements Function<String, List<O>> {
|
||||
private final FormField<String, O> itemField;
|
||||
private final Splitter splitter;
|
||||
|
||||
SplitToListFunction(FormField<String, O> itemField, Splitter splitter) {
|
||||
this.itemField = itemField;
|
||||
this.splitter = splitter;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<O> apply(@Nullable String input) {
|
||||
return input == null
|
||||
? null
|
||||
: Streams.stream(splitter.split(input))
|
||||
.map(itemField.converter)
|
||||
.collect(toImmutableList());
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SplitToSetFunction<O> implements Function<String, Set<O>> {
|
||||
private final FormField<String, O> itemField;
|
||||
private final Splitter splitter;
|
||||
|
||||
SplitToSetFunction(FormField<String, O> itemField, Splitter splitter) {
|
||||
this.itemField = itemField;
|
||||
this.splitter = splitter;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Set<O> apply(@Nullable String input) {
|
||||
return input == null
|
||||
? null
|
||||
: Streams.stream(splitter.split(input))
|
||||
.map(itemField.converter)
|
||||
.collect(toImmutableSet());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
// Copyright 2017 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.forms;
|
||||
|
||||
import static com.google.common.base.MoreObjects.toStringHelper;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import javax.annotation.CheckReturnValue;
|
||||
import javax.annotation.Detainted;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
/**
|
||||
* Exception thrown when a form field contains a bad value.
|
||||
*
|
||||
* <p>You can safely throw {@code FormFieldException} from within your validator functions, and the
|
||||
* field name will automatically be propagated into the exception object for you.
|
||||
*
|
||||
* <p>The way that field names work is a bit complicated, because we need to support complex nested
|
||||
* field names like {@code foo[3].bar}. So what happens is the original exception will be thrown by
|
||||
* a {@link FormField} validator without the field set. Then as the exception bubbles up the stack,
|
||||
* it'll be caught by the {@link FormField#convert(Object) convert} method, which then prepends the
|
||||
* name of that component. Then when the exception reaches the user, the {@link #getFieldName()}
|
||||
* method will produce the fully-qualified field name.
|
||||
*
|
||||
* <p>This propagation mechanism is also very important when writing {@link
|
||||
* FormField.Builder#transform} functions, which oftentimes will not know the name of the field
|
||||
* they're validating.
|
||||
*/
|
||||
@NotThreadSafe
|
||||
@SuppressWarnings("OverrideThrowableToString")
|
||||
public final class FormFieldException extends FormException {
|
||||
|
||||
private final List<Object> names = new ArrayList<>();
|
||||
|
||||
@Nullable
|
||||
private String lazyFieldName;
|
||||
|
||||
/**
|
||||
* Creates a new {@link FormFieldException}
|
||||
*
|
||||
* <p>This exception should only be thrown from within a {@link FormField} converter function.
|
||||
* The field name will automatically be propagated into the exception object for you.
|
||||
*
|
||||
* @param userMessage should be a friendly message that's safe to show to the user.
|
||||
*/
|
||||
public FormFieldException(@Detainted String userMessage) {
|
||||
super(checkNotNull(userMessage, "userMessage"), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link FormFieldException}
|
||||
*
|
||||
* <p>This exception should only be thrown from within a {@link FormField} converter function.
|
||||
* The field name will automatically be propagated into the exception object for you.
|
||||
*
|
||||
* @param userMessage should be a friendly message that's safe to show to the user.
|
||||
* @param cause the original cause of this exception (non-null).
|
||||
*/
|
||||
public FormFieldException(@Detainted String userMessage, Throwable cause) {
|
||||
super(checkNotNull(userMessage, "userMessage"), checkNotNull(cause, "cause"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link FormFieldException} for a particular form field.
|
||||
*
|
||||
* <p>This exception should only be thrown from within a {@link FormField} MAP converter function
|
||||
* in situations where you're performing additional manual validation.
|
||||
*
|
||||
* @param userMessage should be a friendly message that's safe to show to the user.
|
||||
*/
|
||||
public FormFieldException(FormField<?, ?> field, @Detainted String userMessage) {
|
||||
this(field.name(), userMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link FormFieldException} for a particular field name.
|
||||
*
|
||||
* @param field name corresponding to a {@link FormField#name()}
|
||||
* @param userMessage friendly message that's safe to show to the user
|
||||
*/
|
||||
public FormFieldException(String field, @Detainted String userMessage) {
|
||||
super(checkNotNull(userMessage, "userMessage"), null);
|
||||
propagateImpl(field);
|
||||
}
|
||||
|
||||
/** Returns the fully-qualified name (JavaScript syntax) of the form field causing this error. */
|
||||
public String getFieldName() {
|
||||
String fieldName = lazyFieldName;
|
||||
if (fieldName == null) {
|
||||
lazyFieldName = fieldName = getFieldNameImpl();
|
||||
}
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
private String getFieldNameImpl() {
|
||||
checkState(!names.isEmpty(),
|
||||
"FormFieldException was thrown outside FormField infrastructure!");
|
||||
Iterator<Object> namesIterator = Lists.reverse(names).iterator();
|
||||
StringBuilder result = new StringBuilder((String) namesIterator.next());
|
||||
while (namesIterator.hasNext()) {
|
||||
Object name = namesIterator.next();
|
||||
if (name instanceof String) {
|
||||
result.append('.').append(name);
|
||||
} else if (name instanceof Integer) {
|
||||
result.append('[').append(name).append(']');
|
||||
} else {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns self with {@code name} prepended, for propagating exceptions up the stack.
|
||||
*
|
||||
* <p>This would be package-private except that it needs to be called by a test class in another
|
||||
* package.
|
||||
*/
|
||||
@CheckReturnValue
|
||||
public FormFieldException propagate(String name) {
|
||||
return propagateImpl(name);
|
||||
}
|
||||
|
||||
/** Returns self with {@code index} prepended, for propagating exceptions up the stack. */
|
||||
@CheckReturnValue
|
||||
FormFieldException propagate(int index) {
|
||||
return propagateImpl(index);
|
||||
}
|
||||
|
||||
/** Returns self with {@code name} prepended, for propagating exceptions up the stack. */
|
||||
private FormFieldException propagateImpl(Object name) {
|
||||
lazyFieldName = null;
|
||||
names.add(checkNotNull(name));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
return this == obj
|
||||
|| (obj instanceof FormFieldException
|
||||
&& Objects.equals(getCause(), ((FormFieldException) obj).getCause())
|
||||
&& Objects.equals(getMessage(), ((FormFieldException) obj).getMessage())
|
||||
&& Objects.equals(names, ((FormFieldException) obj).names));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getCause(), getMessage(), getFieldName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper(getClass())
|
||||
.add("fieldName", getFieldName())
|
||||
.add("message", getMessage())
|
||||
.add("cause", getCause())
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
// Copyright 2017 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.forms;
|
||||
|
||||
import static com.google.common.collect.Range.atMost;
|
||||
import static com.google.common.collect.Range.closed;
|
||||
import static com.google.common.collect.Range.singleton;
|
||||
import static java.util.Locale.getISOCountries;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.re2j.Pattern;
|
||||
|
||||
/** Utility class of {@link FormField} objects for validating EPP related things. */
|
||||
public final class FormFields {
|
||||
|
||||
private static final Pattern WHITESPACE = Pattern.compile("[ \\t\\r\\n]+");
|
||||
/**
|
||||
* Form field that applies XML Schema Token cleanup to input.
|
||||
*
|
||||
* <p>This trims the input and collapses whitespace.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/TR/xmlschema11-2/#token">XSD Datatypes - token</a>
|
||||
*/
|
||||
public static final FormField<String, String> XS_TOKEN =
|
||||
FormField.named("xsToken")
|
||||
.emptyToNull()
|
||||
.trimmed()
|
||||
.transform(input -> input != null ? WHITESPACE.matcher(input).replaceAll(" ") : null)
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Form field that ensures input does not contain tabs, line feeds, or carriage returns.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/TR/xmlschema11-2/#normalizedString">
|
||||
* XSD Datatypes - normalizedString</a>
|
||||
*/
|
||||
public static final FormField<String, String> XS_NORMALIZED_STRING =
|
||||
FormField.named("xsNormalizedString")
|
||||
.emptyToNull()
|
||||
.matches(Pattern.compile("[^\\t\\r\\n]*"), "Must not contain tabs or multiple lines.")
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Form field for +E164 phone numbers with a dot after the country prefix.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc5733#section-4">RFC 5733 - EPP - Formal Syntax</a>
|
||||
*/
|
||||
public static final FormField<String, String> PHONE_NUMBER =
|
||||
XS_TOKEN.asBuilderNamed("phoneNumber")
|
||||
.range(atMost(17))
|
||||
.matches(Pattern.compile("(\\+[0-9]{1,3}\\.[0-9]{1,14})?"),
|
||||
"Must be a valid +E.164 phone number, e.g. +1.2125650000")
|
||||
.build();
|
||||
|
||||
/** Form field for EPP client identifiers. */
|
||||
public static final FormField<String, String> CLID = XS_TOKEN.asBuilderNamed("clid")
|
||||
.range(closed(3, 16))
|
||||
.build();
|
||||
|
||||
/** Form field for passwords (see pwType in epp.xsd). */
|
||||
public static final FormField<String, String> PASSWORD = XS_TOKEN.asBuilderNamed("password")
|
||||
.range(closed(6, 16))
|
||||
.build();
|
||||
|
||||
/** Form field for non-empty tokens (see minToken in eppcom.xsd). */
|
||||
public static final FormField<String, String> MIN_TOKEN = XS_TOKEN.asBuilderNamed("minToken")
|
||||
.emptyToNull()
|
||||
.build();
|
||||
|
||||
/** Form field for nameType (see rde-registrar/notification). */
|
||||
public static final FormField<String, String> NAME = XS_NORMALIZED_STRING.asBuilderNamed("name")
|
||||
.range(closed(1, 255))
|
||||
.build();
|
||||
|
||||
/** Form field for {@code labelType} from {@code eppcom.xsd}. */
|
||||
public static final FormField<String, String> LABEL = XS_TOKEN.asBuilderNamed("label")
|
||||
.range(closed(1, 255))
|
||||
.build();
|
||||
|
||||
/** Email address form field. */
|
||||
public static final FormField<String, String> EMAIL = XS_TOKEN.asBuilderNamed("email")
|
||||
.matches(Pattern.compile("[^@]+@[^@.]+\\.[^@]+"), "Please enter a valid email address.")
|
||||
.build();
|
||||
|
||||
/** Two-letter ISO country code form field. */
|
||||
public static final FormField<String, String> COUNTRY_CODE =
|
||||
XS_TOKEN.asBuilderNamed("countryCode")
|
||||
.range(singleton(2))
|
||||
.uppercased()
|
||||
.in(ImmutableSet.copyOf(getISOCountries()))
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Ensure value is an EPP Repository Object IDentifier (ROID).
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc5730#section-4.2">Shared Structure Schema</a>
|
||||
*/
|
||||
public static final FormField<String, String> ROID = XS_TOKEN.asBuilderNamed("roid")
|
||||
.matches(Pattern.compile("(\\w|_){1,80}-\\w{1,8}"),
|
||||
"Please enter a valid EPP ROID, e.g. SH8013-REP")
|
||||
.build();
|
||||
|
||||
private FormFields() {}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
// Copyright 2017 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.
|
||||
|
||||
/** Web application backend form processing utilities. */
|
||||
@javax.annotation.ParametersAreNonnullByDefault
|
||||
package google.registry.ui.forms;
|
||||
@@ -1,15 +0,0 @@
|
||||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>Server Error</title>
|
||||
<style>
|
||||
*{margin:0;padding:0}
|
||||
html,code{font:15px/22px arial,sans-serif}
|
||||
html{background:#fff;color:#222;padding:15px}
|
||||
body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}
|
||||
* > body{background:url(/manager/img/ui/robot.png) 100% 5px no-repeat;padding-right:205px}
|
||||
p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}
|
||||
a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}
|
||||
</style>
|
||||
<a href="/"><img src="/assets/images/logo_sm.gif" alt=Google></a>
|
||||
<p><b>500.</b> <ins>That's an error.</ins>
|
||||
<p>Sorry, but the server encountered an error while processing your request.
|
||||
@@ -1,6 +0,0 @@
|
||||
<!doctype html>
|
||||
<meta http-equiv="refresh" content="0;URL=/console">
|
||||
<title>Nomulus</title>
|
||||
<body lang="en-US">
|
||||
If this page doesn't change automatically, please go
|
||||
to <a href="/console">https://www.registry.google/console</a>
|
||||
@@ -1,16 +0,0 @@
|
||||
// Copyright 2017 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.
|
||||
|
||||
@javax.annotation.ParametersAreNonnullByDefault
|
||||
package google.registry.ui;
|
||||
@@ -1,82 +0,0 @@
|
||||
// Copyright 2017 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;
|
||||
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
|
||||
/**
|
||||
* Bimap of state codes and names for the US Regime.
|
||||
*
|
||||
* @see <a href="http://statetable.com/">State Table</a>
|
||||
*/
|
||||
public final class StateCode {
|
||||
|
||||
public static final ImmutableBiMap<String, String> US_MAP =
|
||||
new ImmutableBiMap.Builder<String, String>()
|
||||
.put("AL", "Alabama")
|
||||
.put("AK", "Alaska")
|
||||
.put("AZ", "Arizona")
|
||||
.put("AR", "Arkansas")
|
||||
.put("CA", "California")
|
||||
.put("CO", "Colorado")
|
||||
.put("CT", "Connecticut")
|
||||
.put("DE", "Delaware")
|
||||
.put("FL", "Florida")
|
||||
.put("GA", "Georgia")
|
||||
.put("HI", "Hawaii")
|
||||
.put("ID", "Idaho")
|
||||
.put("IL", "Illinois")
|
||||
.put("IN", "Indiana")
|
||||
.put("IA", "Iowa")
|
||||
.put("KS", "Kansas")
|
||||
.put("KY", "Kentucky")
|
||||
.put("LA", "Louisiana")
|
||||
.put("ME", "Maine")
|
||||
.put("MD", "Maryland")
|
||||
.put("MA", "Massachusetts")
|
||||
.put("MI", "Michigan")
|
||||
.put("MN", "Minnesota")
|
||||
.put("MS", "Mississippi")
|
||||
.put("MO", "Missouri")
|
||||
.put("MT", "Montana")
|
||||
.put("NE", "Nebraska")
|
||||
.put("NV", "Nevada")
|
||||
.put("NH", "New Hampshire")
|
||||
.put("NJ", "New Jersey")
|
||||
.put("NM", "New Mexico")
|
||||
.put("NY", "New York")
|
||||
.put("NC", "North Carolina")
|
||||
.put("ND", "North Dakota")
|
||||
.put("OH", "Ohio")
|
||||
.put("OK", "Oklahoma")
|
||||
.put("OR", "Oregon")
|
||||
.put("PA", "Pennsylvania")
|
||||
.put("RI", "Rhode Island")
|
||||
.put("SC", "South Carolina")
|
||||
.put("SD", "South Dakota")
|
||||
.put("TN", "Tennessee")
|
||||
.put("TX", "Texas")
|
||||
.put("UT", "Utah")
|
||||
.put("VT", "Vermont")
|
||||
.put("VA", "Virginia")
|
||||
.put("WA", "Washington")
|
||||
.put("WV", "West Virginia")
|
||||
.put("WI", "Wisconsin")
|
||||
.put("WY", "Wyoming")
|
||||
.put("DC", "Washington DC")
|
||||
.build();
|
||||
|
||||
private StateCode() {}
|
||||
}
|
||||
+4
-4
@@ -79,17 +79,17 @@ public class ConsoleUpdateRegistrarAction extends ConsoleApiAction {
|
||||
registrarParam.getRegistrarId());
|
||||
|
||||
// Only allow modifying allowed TLDs if we're in a non-PRODUCTION environment, if the
|
||||
// registrar is not REAL, or the registrar has a WHOIS abuse contact set.
|
||||
// registrar is not REAL, or the registrar has a RDAP abuse contact set.
|
||||
if (!registrarParam.getAllowedTlds().isEmpty()) {
|
||||
boolean isRealRegistrar =
|
||||
Registrar.Type.REAL.equals(existingRegistrar.get().getType());
|
||||
if (RegistryEnvironment.PRODUCTION.equals(RegistryEnvironment.get())
|
||||
&& isRealRegistrar) {
|
||||
checkArgumentPresent(
|
||||
existingRegistrar.get().getWhoisAbuseContact(),
|
||||
"Cannot modify allowed TLDs if there is no WHOIS abuse contact set. Please"
|
||||
existingRegistrar.get().getRdapAbuseContact(),
|
||||
"Cannot modify allowed TLDs if there is no RDAP abuse contact set. Please"
|
||||
+ " use the \"nomulus registrar_contact\" command on this registrar to"
|
||||
+ " set a WHOIS abuse contact.");
|
||||
+ " set a RDAP abuse contact.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@ import google.registry.request.Action.GaeService;
|
||||
import google.registry.request.Action.GkeService;
|
||||
import google.registry.request.Parameter;
|
||||
import google.registry.request.auth.Auth;
|
||||
import google.registry.ui.forms.FormException;
|
||||
import google.registry.ui.server.console.ConsoleApiAction;
|
||||
import google.registry.ui.server.console.ConsoleApiParams;
|
||||
import jakarta.inject.Inject;
|
||||
@@ -106,9 +105,9 @@ public class ContactAction extends ConsoleApiAction {
|
||||
new RegistrarPoc()
|
||||
.asBuilder()
|
||||
.setTypes(newContact.getTypes())
|
||||
.setVisibleInWhoisAsTech(newContact.getVisibleInWhoisAsTech())
|
||||
.setVisibleInWhoisAsAdmin(newContact.getVisibleInWhoisAsAdmin())
|
||||
.setVisibleInDomainWhoisAsAbuse(newContact.getVisibleInDomainWhoisAsAbuse())
|
||||
.setVisibleInRdapAsTech(newContact.getVisibleInRdapAsTech())
|
||||
.setVisibleInRdapAsAdmin(newContact.getVisibleInRdapAsAdmin())
|
||||
.setVisibleInDomainRdapAsAbuse(newContact.getVisibleInDomainRdapAsAbuse())
|
||||
.setFaxNumber(newContact.getFaxNumber())
|
||||
.setName(newContact.getName())
|
||||
.setEmailAddress(newContact.getEmailAddress())
|
||||
@@ -133,10 +132,10 @@ public class ContactAction extends ConsoleApiAction {
|
||||
? oldContact
|
||||
.asBuilder()
|
||||
.setTypes(updatedContact.getTypes())
|
||||
.setVisibleInWhoisAsTech(updatedContact.getVisibleInWhoisAsTech())
|
||||
.setVisibleInWhoisAsAdmin(updatedContact.getVisibleInWhoisAsAdmin())
|
||||
.setVisibleInDomainWhoisAsAbuse(
|
||||
updatedContact.getVisibleInDomainWhoisAsAbuse())
|
||||
.setVisibleInRdapAsTech(updatedContact.getVisibleInRdapAsTech())
|
||||
.setVisibleInRdapAsAdmin(updatedContact.getVisibleInRdapAsAdmin())
|
||||
.setVisibleInDomainRdapAsAbuse(
|
||||
updatedContact.getVisibleInDomainRdapAsAbuse())
|
||||
.setFaxNumber(updatedContact.getFaxNumber())
|
||||
.setName(updatedContact.getName())
|
||||
.setEmailAddress(updatedContact.getEmailAddress())
|
||||
@@ -166,7 +165,7 @@ public class ContactAction extends ConsoleApiAction {
|
||||
|
||||
try {
|
||||
checkContactRequirements(oldContacts, newContacts);
|
||||
} catch (FormException e) {
|
||||
} catch (ContactRequirementException e) {
|
||||
logger.atWarning().withCause(e).log(
|
||||
"Error processing contacts post request for registrar: %s", registrarId);
|
||||
throw new IllegalArgumentException(e);
|
||||
@@ -196,7 +195,7 @@ public class ContactAction extends ConsoleApiAction {
|
||||
/**
|
||||
* Enforces business logic checks on registrar contacts.
|
||||
*
|
||||
* @throws FormException if the checks fail.
|
||||
* @throws ContactRequirementException if the checks fail.
|
||||
*/
|
||||
private static void checkContactRequirements(
|
||||
ImmutableSet<RegistrarPoc> existingContacts, ImmutableSet<RegistrarPoc> updatedContacts) {
|
||||
@@ -231,19 +230,19 @@ public class ContactAction extends ConsoleApiAction {
|
||||
|
||||
enforcePrimaryContactRestrictions(oldContactsByType, newContactsByType);
|
||||
ensurePhoneNumberNotRemovedForContactTypes(oldContactsByType, newContactsByType, Type.TECH);
|
||||
Optional<RegistrarPoc> domainWhoisAbuseContact =
|
||||
getDomainWhoisVisibleAbuseContact(updatedContacts);
|
||||
// If the new set has a domain WHOIS abuse contact, it must have a phone number.
|
||||
if (domainWhoisAbuseContact.isPresent()
|
||||
&& domainWhoisAbuseContact.get().getPhoneNumber() == null) {
|
||||
Optional<RegistrarPoc> domainRdapAbuseContact =
|
||||
getDomainRdapVisibleAbuseContact(updatedContacts);
|
||||
// If the new set has a domain RDAP abuse contact, it must have a phone number.
|
||||
if (domainRdapAbuseContact.isPresent()
|
||||
&& domainRdapAbuseContact.get().getPhoneNumber() == null) {
|
||||
throw new ContactRequirementException(
|
||||
"The abuse contact visible in domain WHOIS query must have a phone number");
|
||||
"The abuse contact visible in domain RDAP query must have a phone number");
|
||||
}
|
||||
// If there was a domain WHOIS abuse contact in the old set, the new set must have one.
|
||||
if (getDomainWhoisVisibleAbuseContact(existingContacts).isPresent()
|
||||
&& domainWhoisAbuseContact.isEmpty()) {
|
||||
// If there was a domain RDAP abuse contact in the old set, the new set must have one.
|
||||
if (getDomainRdapVisibleAbuseContact(existingContacts).isPresent()
|
||||
&& domainRdapAbuseContact.isEmpty()) {
|
||||
throw new ContactRequirementException(
|
||||
"An abuse contact visible in domain WHOIS query must be designated");
|
||||
"An abuse contact visible in domain RDAP query must be designated");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,17 +264,17 @@ public class ContactAction extends ConsoleApiAction {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the registrar contact whose phone number and email address is visible in domain WHOIS
|
||||
* Retrieves the registrar contact whose phone number and email address is visible in domain RDAP
|
||||
* query as abuse contact (if any).
|
||||
*
|
||||
* <p>Frontend processing ensures that only one contact can be set as abuse contact in domain
|
||||
* WHOIS record.
|
||||
* <p>Frontend processing ensures that only one contact can be set as abuse contact in domain RDAP
|
||||
* record.
|
||||
*
|
||||
* <p>Therefore, it is possible to return inside the loop once one such contact is found.
|
||||
*/
|
||||
private static Optional<RegistrarPoc> getDomainWhoisVisibleAbuseContact(
|
||||
private static Optional<RegistrarPoc> getDomainRdapVisibleAbuseContact(
|
||||
Set<RegistrarPoc> contacts) {
|
||||
return contacts.stream().filter(RegistrarPoc::getVisibleInDomainWhoisAsAbuse).findFirst();
|
||||
return contacts.stream().filter(RegistrarPoc::getVisibleInDomainRdapAsAbuse).findFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -299,7 +298,7 @@ public class ContactAction extends ConsoleApiAction {
|
||||
}
|
||||
|
||||
/** Thrown when a set of contacts doesn't meet certain constraints. */
|
||||
private static class ContactRequirementException extends FormException {
|
||||
private static class ContactRequirementException extends RuntimeException {
|
||||
ContactRequirementException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
// Copyright 2017 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.
|
||||
|
||||
@javax.annotation.ParametersAreNonnullByDefault
|
||||
package google.registry.ui.server;
|
||||
+7
-7
@@ -221,8 +221,8 @@ class SendExpiringCertificateNotificationEmailActionTest {
|
||||
.setPhoneNumber("+1.3105551213")
|
||||
.setFaxNumber("+1.3105551213")
|
||||
.setTypes(ImmutableSet.of(RegistrarPoc.Type.TECH))
|
||||
.setVisibleInWhoisAsAdmin(true)
|
||||
.setVisibleInWhoisAsTech(false)
|
||||
.setVisibleInRdapAsAdmin(true)
|
||||
.setVisibleInRdapAsTech(false)
|
||||
.build());
|
||||
persistResources(contacts);
|
||||
RuntimeException thrown =
|
||||
@@ -511,8 +511,8 @@ class SendExpiringCertificateNotificationEmailActionTest {
|
||||
.setPhoneNumber("+1.3105551213")
|
||||
.setFaxNumber("+1.3105551213")
|
||||
.setTypes(ImmutableSet.of(RegistrarPoc.Type.TECH))
|
||||
.setVisibleInWhoisAsAdmin(true)
|
||||
.setVisibleInWhoisAsTech(false)
|
||||
.setVisibleInRdapAsAdmin(true)
|
||||
.setVisibleInRdapAsTech(false)
|
||||
.build(),
|
||||
new RegistrarPoc.Builder()
|
||||
.setRegistrar(registrar)
|
||||
@@ -529,8 +529,8 @@ class SendExpiringCertificateNotificationEmailActionTest {
|
||||
.setPhoneNumber("+1.3105551213")
|
||||
.setFaxNumber("+1.3105551213")
|
||||
.setTypes(ImmutableSet.of(RegistrarPoc.Type.TECH))
|
||||
.setVisibleInWhoisAsAdmin(true)
|
||||
.setVisibleInWhoisAsTech(false)
|
||||
.setVisibleInRdapAsAdmin(true)
|
||||
.setVisibleInRdapAsTech(false)
|
||||
.build(),
|
||||
new RegistrarPoc.Builder()
|
||||
.setRegistrar(registrar)
|
||||
@@ -547,7 +547,7 @@ class SendExpiringCertificateNotificationEmailActionTest {
|
||||
.setPhoneNumber("+1.3105551215")
|
||||
.setFaxNumber("+1.3105551216")
|
||||
.setTypes(ImmutableSet.of(RegistrarPoc.Type.ADMIN))
|
||||
.setVisibleInWhoisAsTech(true)
|
||||
.setVisibleInRdapAsTech(true)
|
||||
.build());
|
||||
persistResources(contacts);
|
||||
assertThat(action.getEmailAddresses(registrar, Type.TECH))
|
||||
|
||||
@@ -168,8 +168,8 @@ public class SyncRegistrarsSheetTest {
|
||||
.setTypes(ImmutableSet.of(RegistrarPoc.Type.ADMIN))
|
||||
// Purposely flip the internal/external admin/tech
|
||||
// distinction to make sure we're not relying on it. Sigh.
|
||||
.setVisibleInWhoisAsAdmin(false)
|
||||
.setVisibleInWhoisAsTech(true)
|
||||
.setVisibleInRdapAsAdmin(false)
|
||||
.setVisibleInRdapAsTech(true)
|
||||
.build(),
|
||||
new RegistrarPoc.Builder()
|
||||
.setRegistrar(registrar)
|
||||
@@ -201,9 +201,9 @@ public class SyncRegistrarsSheetTest {
|
||||
contact@example.com
|
||||
Tel: +1.1234567890
|
||||
Types: [ADMIN, BILLING]
|
||||
Visible in registrar WHOIS query as Admin contact: No
|
||||
Visible in registrar WHOIS query as Technical contact: No
|
||||
Phone number and email visible in domain WHOIS query as Registrar Abuse contact\
|
||||
Visible in registrar RDAP query as Admin contact: No
|
||||
Visible in registrar RDAP query as Technical contact: No
|
||||
Phone number and email visible in domain RDAP query as Registrar Abuse contact\
|
||||
info: No
|
||||
|
||||
John Doe
|
||||
@@ -211,9 +211,9 @@ public class SyncRegistrarsSheetTest {
|
||||
Tel: +1.1234567890
|
||||
Fax: +1.1234567891
|
||||
Types: [ADMIN]
|
||||
Visible in registrar WHOIS query as Admin contact: No
|
||||
Visible in registrar WHOIS query as Technical contact: Yes
|
||||
Phone number and email visible in domain WHOIS query as Registrar Abuse contact\
|
||||
Visible in registrar RDAP query as Admin contact: No
|
||||
Visible in registrar RDAP query as Technical contact: Yes
|
||||
Phone number and email visible in domain RDAP query as Registrar Abuse contact\
|
||||
info: No
|
||||
""");
|
||||
assertThat(row)
|
||||
@@ -223,9 +223,9 @@ public class SyncRegistrarsSheetTest {
|
||||
Jane Smith
|
||||
pride@example.net
|
||||
Types: [TECH]
|
||||
Visible in registrar WHOIS query as Admin contact: No
|
||||
Visible in registrar WHOIS query as Technical contact: No
|
||||
Phone number and email visible in domain WHOIS query as Registrar Abuse contact\
|
||||
Visible in registrar RDAP query as Admin contact: No
|
||||
Visible in registrar RDAP query as Technical contact: No
|
||||
Phone number and email visible in domain RDAP query as Registrar Abuse contact\
|
||||
info: No
|
||||
""");
|
||||
assertThat(row).containsEntry("marketingContacts", "");
|
||||
@@ -240,9 +240,9 @@ public class SyncRegistrarsSheetTest {
|
||||
contact@example.com
|
||||
Tel: +1.1234567890
|
||||
Types: [ADMIN, BILLING]
|
||||
Visible in registrar WHOIS query as Admin contact: No
|
||||
Visible in registrar WHOIS query as Technical contact: No
|
||||
Phone number and email visible in domain WHOIS query as Registrar Abuse contact\
|
||||
Visible in registrar RDAP query as Admin contact: No
|
||||
Visible in registrar RDAP query as Technical contact: No
|
||||
Phone number and email visible in domain RDAP query as Registrar Abuse contact\
|
||||
info: No
|
||||
""");
|
||||
assertThat(row).containsEntry("contactsMarkedAsWhoisAdmin", "");
|
||||
@@ -255,9 +255,9 @@ public class SyncRegistrarsSheetTest {
|
||||
Tel: +1.1234567890
|
||||
Fax: +1.1234567891
|
||||
Types: [ADMIN]
|
||||
Visible in registrar WHOIS query as Admin contact: No
|
||||
Visible in registrar WHOIS query as Technical contact: Yes
|
||||
Phone number and email visible in domain WHOIS query as Registrar Abuse contact\
|
||||
Visible in registrar RDAP query as Admin contact: No
|
||||
Visible in registrar RDAP query as Technical contact: Yes
|
||||
Phone number and email visible in domain RDAP query as Registrar Abuse contact\
|
||||
info: No
|
||||
""");
|
||||
assertThat(row).containsEntry("emailAddress", "nowhere@example.org");
|
||||
|
||||
@@ -126,8 +126,8 @@ class RegistrarTest extends EntityTestCase {
|
||||
.setRegistrar(registrar)
|
||||
.setName("John Abused")
|
||||
.setEmailAddress("johnabuse@example.com")
|
||||
.setVisibleInWhoisAsAdmin(true)
|
||||
.setVisibleInWhoisAsTech(false)
|
||||
.setVisibleInRdapAsAdmin(true)
|
||||
.setVisibleInRdapAsTech(false)
|
||||
.setPhoneNumber("+1.2125551213")
|
||||
.setFaxNumber("+1.2125551213")
|
||||
.setTypes(ImmutableSet.of(RegistrarPoc.Type.ABUSE, RegistrarPoc.Type.ADMIN))
|
||||
@@ -323,8 +323,8 @@ class RegistrarTest extends EntityTestCase {
|
||||
.setRegistrar(registrar)
|
||||
.setName("Jake Tech")
|
||||
.setEmailAddress("jaketech@example.com")
|
||||
.setVisibleInWhoisAsAdmin(true)
|
||||
.setVisibleInWhoisAsTech(true)
|
||||
.setVisibleInRdapAsAdmin(true)
|
||||
.setVisibleInRdapAsTech(true)
|
||||
.setPhoneNumber("+1.2125551213")
|
||||
.setFaxNumber("+1.2125551213")
|
||||
.setTypes(ImmutableSet.of(RegistrarPoc.Type.TECH))
|
||||
@@ -335,8 +335,8 @@ class RegistrarTest extends EntityTestCase {
|
||||
.setRegistrar(registrar)
|
||||
.setName("Jim Tech-Abuse")
|
||||
.setEmailAddress("jimtechAbuse@example.com")
|
||||
.setVisibleInWhoisAsAdmin(true)
|
||||
.setVisibleInWhoisAsTech(true)
|
||||
.setVisibleInRdapAsAdmin(true)
|
||||
.setVisibleInRdapAsTech(true)
|
||||
.setPhoneNumber("+1.2125551213")
|
||||
.setFaxNumber("+1.2125551213")
|
||||
.setTypes(ImmutableSet.of(RegistrarPoc.Type.TECH, RegistrarPoc.Type.ABUSE))
|
||||
|
||||
@@ -18,29 +18,14 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import google.registry.module.backend.BackendRequestComponent;
|
||||
import google.registry.module.bsa.BsaRequestComponent;
|
||||
import google.registry.module.frontend.FrontendRequestComponent;
|
||||
import google.registry.module.pubapi.PubApiRequestComponent;
|
||||
import google.registry.module.tools.ToolsRequestComponent;
|
||||
import google.registry.testing.GoldenFileTestHelper;
|
||||
import google.registry.testing.TestDataHelper;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Unit tests for {@link RequestComponent}. */
|
||||
public class RequestComponentTest {
|
||||
private static final ImmutableMap<Class<?>, String> GaeComponents =
|
||||
ImmutableMap.of(
|
||||
FrontendRequestComponent.class, "frontend",
|
||||
BackendRequestComponent.class, "backend",
|
||||
ToolsRequestComponent.class, "tools",
|
||||
PubApiRequestComponent.class, "pubapi",
|
||||
BsaRequestComponent.class, "bsa");
|
||||
|
||||
@Test
|
||||
void testRoutingMap() {
|
||||
@@ -49,17 +34,6 @@ public class RequestComponentTest {
|
||||
.isEqualToGolden(RequestComponentTest.class, "routing.txt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("To be removed with GAE components")
|
||||
void testGaeToJettyRoutingCoverage() {
|
||||
Set<Route> jettyRoutes = getRoutes(RequestComponent.class, "routing.txt");
|
||||
Set<Route> gaeRoutes = new HashSet<>();
|
||||
for (var component : GaeComponents.entrySet()) {
|
||||
gaeRoutes.addAll(getRoutes(component.getKey(), component.getValue() + "_routing.txt"));
|
||||
}
|
||||
assertThat(jettyRoutes).isEqualTo(gaeRoutes);
|
||||
}
|
||||
|
||||
private Set<Route> getRoutes(Class<?> context, String filename) {
|
||||
return TestDataHelper.loadFile(context, filename)
|
||||
.trim()
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
// Copyright 2023 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.module.bsa;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import google.registry.request.Action.GaeService;
|
||||
import google.registry.request.RouterDisplayHelper;
|
||||
import google.registry.testing.GoldenFileTestHelper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Unit tests for {@link BsaRequestComponent}. */
|
||||
public class BsaRequestComponentTest {
|
||||
|
||||
@Test
|
||||
void testRoutingMap() {
|
||||
GoldenFileTestHelper.assertThatRoutesFromComponent(BsaRequestComponent.class)
|
||||
.describedAs("bsa routing map")
|
||||
.isEqualToGolden(BsaRequestComponent.class, "bsa_routing.txt");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRoutingService() {
|
||||
assertThat(
|
||||
RouterDisplayHelper.extractHumanReadableRoutesWithWrongService(
|
||||
BsaRequestComponent.class, GaeService.BSA))
|
||||
.isEmpty();
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
// Copyright 2023 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.module.bsa;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class BsaServletTest {
|
||||
private final HttpServletRequest req = mock(HttpServletRequest.class);
|
||||
private final HttpServletResponse rsp = mock(HttpServletResponse.class);
|
||||
|
||||
@Test
|
||||
void testService_unknownPath_returnsNotFound() throws Exception {
|
||||
when(req.getMethod()).thenReturn("GET");
|
||||
when(req.getRequestURI()).thenReturn("/lol");
|
||||
new BsaServlet().service(req, rsp);
|
||||
verify(rsp).sendError(404);
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,6 @@ import google.registry.monitoring.whitebox.StackdriverModule;
|
||||
import google.registry.privileges.secretmanager.SecretManagerModule;
|
||||
import google.registry.request.Modules;
|
||||
import google.registry.request.auth.AuthModule;
|
||||
import google.registry.ui.ConsoleDebug;
|
||||
import google.registry.util.UtilsModule;
|
||||
import jakarta.inject.Singleton;
|
||||
|
||||
@@ -40,7 +39,6 @@ import jakarta.inject.Singleton;
|
||||
AuthModule.class,
|
||||
CloudTasksUtilsModule.class,
|
||||
RegistryConfig.ConfigModule.class,
|
||||
ConsoleDebug.ConsoleConfigModule.class,
|
||||
CredentialModule.class,
|
||||
CustomLogicFactoryModule.class,
|
||||
CloudTasksUtilsModule.class,
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
// Copyright 2018 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.module.pubapi;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import google.registry.request.Action.GaeService;
|
||||
import google.registry.request.RouterDisplayHelper;
|
||||
import google.registry.testing.GoldenFileTestHelper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Unit tests for {@link PubApiRequestComponent}. */
|
||||
class PubApiRequestComponentTest {
|
||||
|
||||
@Test
|
||||
void testRoutingMap() {
|
||||
GoldenFileTestHelper.assertThatRoutesFromComponent(PubApiRequestComponent.class)
|
||||
.describedAs("pubapi routing map")
|
||||
.isEqualToGolden(PubApiRequestComponentTest.class, "pubapi_routing.txt");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRoutingService() {
|
||||
assertThat(
|
||||
RouterDisplayHelper.extractHumanReadableRoutesWithWrongService(
|
||||
PubApiRequestComponent.class, GaeService.PUBAPI))
|
||||
.isEmpty();
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
// Copyright 2018 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.module.pubapi;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Unit tests for {@link PubApiServlet}. */
|
||||
class PubApiServletTest {
|
||||
|
||||
private final HttpServletRequest req = mock(HttpServletRequest.class);
|
||||
private final HttpServletResponse rsp = mock(HttpServletResponse.class);
|
||||
|
||||
@Test
|
||||
void testService_unknownPath_returnNotFound() throws Exception {
|
||||
when(req.getMethod()).thenReturn("GET");
|
||||
when(req.getRequestURI()).thenReturn("/lol");
|
||||
new PubApiServlet().service(req, rsp);
|
||||
verify(rsp).sendError(404);
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
// Copyright 2017 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.module.tools;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import google.registry.request.Action.GaeService;
|
||||
import google.registry.request.RouterDisplayHelper;
|
||||
import google.registry.testing.GoldenFileTestHelper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Unit tests for {@link ToolsRequestComponent}. */
|
||||
class ToolsRequestComponentTest {
|
||||
|
||||
@Test
|
||||
void testRoutingMap() {
|
||||
GoldenFileTestHelper.assertThatRoutesFromComponent(ToolsRequestComponent.class)
|
||||
.describedAs("tools routing map")
|
||||
.isEqualToGolden(ToolsRequestComponentTest.class, "tools_routing.txt");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRoutingService() {
|
||||
assertThat(
|
||||
RouterDisplayHelper.extractHumanReadableRoutesWithWrongService(
|
||||
ToolsRequestComponent.class, GaeService.TOOLS))
|
||||
.isEmpty();
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
// Copyright 2017 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.module.tools;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Unit tests for {@link ToolsServlet}. */
|
||||
class ToolsServletTest {
|
||||
|
||||
private final HttpServletRequest req = mock(HttpServletRequest.class);
|
||||
private final HttpServletResponse rsp = mock(HttpServletResponse.class);
|
||||
|
||||
@Test
|
||||
void testService_unknownPath_returnsNotFound() throws Exception {
|
||||
when(req.getMethod()).thenReturn("GET");
|
||||
when(req.getRequestURI()).thenReturn("/lol");
|
||||
new ToolsServlet().service(req, rsp);
|
||||
verify(rsp).sendError(404);
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -407,8 +407,8 @@ public abstract class JpaTransactionManagerExtension
|
||||
return new RegistrarPoc.Builder()
|
||||
.setRegistrar(makeRegistrar1())
|
||||
.setName("Jane Doe")
|
||||
.setVisibleInWhoisAsAdmin(true)
|
||||
.setVisibleInWhoisAsTech(false)
|
||||
.setVisibleInRdapAsAdmin(true)
|
||||
.setVisibleInRdapAsTech(false)
|
||||
.setEmailAddress("janedoe@theregistrar.com")
|
||||
.setPhoneNumber("+1.1234567890")
|
||||
.setTypes(ImmutableSet.of(RegistrarPoc.Type.ADMIN))
|
||||
|
||||
@@ -198,8 +198,8 @@ class RdapJsonFormatterTest {
|
||||
.setPhoneNumber("+1.2125551217")
|
||||
.setFaxNumber("+1.2125551218")
|
||||
.setTypes(ImmutableSet.of(RegistrarPoc.Type.ADMIN))
|
||||
.setVisibleInWhoisAsAdmin(false)
|
||||
.setVisibleInWhoisAsTech(false)
|
||||
.setVisibleInRdapAsAdmin(false)
|
||||
.setVisibleInRdapAsTech(false)
|
||||
.build(),
|
||||
new RegistrarPoc.Builder()
|
||||
.setRegistrar(registrar)
|
||||
@@ -207,8 +207,8 @@ class RdapJsonFormatterTest {
|
||||
.setEmailAddress("johndoe@example.com")
|
||||
.setFaxNumber("+1.2125551213")
|
||||
.setTypes(ImmutableSet.of(RegistrarPoc.Type.ADMIN))
|
||||
.setVisibleInWhoisAsAdmin(false)
|
||||
.setVisibleInWhoisAsTech(true)
|
||||
.setVisibleInRdapAsAdmin(false)
|
||||
.setVisibleInRdapAsTech(true)
|
||||
.build(),
|
||||
new RegistrarPoc.Builder()
|
||||
.setRegistrar(registrar)
|
||||
@@ -216,8 +216,8 @@ class RdapJsonFormatterTest {
|
||||
.setEmailAddress("janedoe@example.com")
|
||||
.setPhoneNumber("+1.2125551215")
|
||||
.setTypes(ImmutableSet.of(RegistrarPoc.Type.TECH, RegistrarPoc.Type.ADMIN))
|
||||
.setVisibleInWhoisAsAdmin(true)
|
||||
.setVisibleInWhoisAsTech(false)
|
||||
.setVisibleInRdapAsAdmin(true)
|
||||
.setVisibleInRdapAsTech(false)
|
||||
.build(),
|
||||
new RegistrarPoc.Builder()
|
||||
.setRegistrar(registrar)
|
||||
@@ -226,8 +226,8 @@ class RdapJsonFormatterTest {
|
||||
.setPhoneNumber("+1.2125551217")
|
||||
.setFaxNumber("+1.2125551218")
|
||||
.setTypes(ImmutableSet.of(RegistrarPoc.Type.BILLING))
|
||||
.setVisibleInWhoisAsAdmin(true)
|
||||
.setVisibleInWhoisAsTech(true)
|
||||
.setVisibleInRdapAsAdmin(true)
|
||||
.setVisibleInRdapAsTech(true)
|
||||
.build());
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user