1
0
mirror of https://github.com/google/nomulus synced 2026-06-09 16:33:02 +00:00

Compare commits

...

42 Commits

Author SHA1 Message Date
Weimin Yu b3e67e58b5 Change billing for multi-year domain creation (#2446)
* Change billing for multi-year domain creation

From the second year on, charge the renewal price.

See b/322833077
2024-05-29 13:19:54 -04:00
gbrodman 589041b3ed Fully reset domain-list page on registrar change (#2456)
When the registrar changes we should reset the page and the total
results to 0 (since we haven't loaded them yet)

https://b.corp.google.com/issues/343193698
2024-05-29 12:54:01 -04:00
Lai Jiang 455364ff29 Remove GAE Users service API usage (#2414)
This is the last remaining GAE API that we depend on. By removing it, we are able to remove all common GAE dependencies as well.

To merge this PR, we need to create console User objects that have the same email address as the RegistrarPoc objects' login_email_address and copy over the existing registry lock hashes and salts.

We are also able to simply the code base by removing some redundant logic like AuthMethod (API is now the only supported one) and UserAuthInfo (console user is now the only supported one)

There are several behavioral changes that are worth noting:

The XsrfTokenManager now uses the console user's email address to mint and verify the token. Previously, only email addresses returned by the GAE Users service are used, whereas a blank email address will be used if the user is logged in as a console user. I believe this was an oversight that is now corrected.
The legacy console will return 401 when no user is logged in, instead of redirecting to the Users service login flow.
The logout URL in the legacy console is changed to use the IAP logout flow. It will clear the cookie and redirect the users to IAP login page (tested on QA).
The screenshot changes are mostly due to the console users lacking a display name and therefore showing the email address instead. Some changes are due to using the console user's email address as the registry lock email address, which is being fixed in Add DB column for separate rlock email address #2413 and its follow-up RPs.
2024-05-29 12:37:44 -04:00
Lai Jiang d90bc1a3e4 Update db README (#2449) 2024-05-29 11:54:31 -04:00
Lai Jiang 0e3875c1ff Removing leading newline from GKE log messages (#2454)
GKE now displays log messages correctly. There is no need for an extra
leading newline, which now results in a useless blank line for each log
entry in Log Explorer.
2024-05-29 11:54:19 -04:00
Lai Jiang 3b565b96b7 Add the ability to add/remove console users from a Google Group (#2450)
# Conflicts:
#	config/presubmits.py
2024-05-28 17:00:37 +00:00
Pavlo Tkach ec6c77927f Add console backend for editing registrar (#2452) 2024-05-28 00:53:32 +00:00
Lai Jiang e88ff77ecb Harmonize http status code usage (#2451)
Given that we run servlets, it makes sense to always use the status
code contants from the servlet class.
2024-05-24 18:46:37 +00:00
sarahcaseybot 0781010b16 Create a load testing EPP client (#2415)
* Create a load testing EPP client.

This code is mostly based off of what was used for a past EPP load testing client that can be found in Google3 at https://source.corp.google.com/piper///depot/google3/experimental/users/jianglai/proxy/java/google/registry/proxy/client/

I modified the old client to be open-source friendly and use Gradle.

For now, this only performs a login and logout command, I will further expand on this in later PRs to add other EPP commands so that we can truly load test the system.

* Small changes

* Remove unnecessary build dep

* Add gradle build tasks

* Small fixes

* Add an instances setUp and cleanUp script

* More modifications to instance setup scripts

* change to ubuntu instance

* Add comment to make ssh work
2024-05-23 21:37:34 +00:00
Pavlo Tkach ab4bac05d1 Replace RegistryTestServerMain start address with ipv6 loopback (#2448) 2024-05-21 19:00:25 +00:00
Pavlo Tkach 8e22ce7c70 Add phone and fax number to console whois endpoint (#2447) 2024-05-20 20:32:23 +00:00
Lai Jiang d96a5547ce Store stack trace in a separate filed during logging (#2444)
For reasons unclear to me, if the stack trace is appended directly to
the message, the log entry will be lumped together with following logs
on GKE.

Also updated the GKE service account for Nomulus in the manifest so we
can use workload identity just for Nomulus, not other pods on the same
cluster.
2024-05-20 16:17:56 +00:00
Pavlo Tkach 05b43965d1 Fix console EPP password form, minor adjustments (#2445) 2024-05-17 18:44:44 +00:00
gbrodman 43000a5f80 Refactor common exception handling in ConsoleApiAction (#2443)
There are a bunch of cases where we want common exception handling and
it's annoying to have to deal with the common "set failed response and
make sure to return" a bunch of times.

This allows us to break up request methods more easily, since we can now
often throw exceptions that will break all the way back up to
ConsoleApiAction. Previously, any error handling had to exist in the
primary handler method so it could return.
2024-05-16 18:29:14 +00:00
Pavlo Tkach a66b9ea749 Add OTE registrars to console /registrars response (#2440) 2024-05-16 14:49:32 +00:00
sarahcaseybot 36a660a8ad Remove createBillingCost columns from db schema (#2438) 2024-05-15 18:19:36 +00:00
gbrodman d09bb4ff74 Refactor some registry lock verification code (#2434)
The user, on the front end, should not be required to provide whether or
not they're trying to verify a lock or an unlock. They should only need
the verification code. We can inspect the lock object itself (and the
domain in question) to see whether or not we're verifying a lock or an
unlock.
2024-05-14 16:56:32 +00:00
Lai Jiang 6ca3cc230f Make logging work correctly on Jetty (#2442) 2024-05-14 14:36:26 +00:00
Pavlo Tkach 6a5d8ed3b5 Allow console access for all not NONE-type global users (#2441) 2024-05-13 19:24:11 +00:00
Pavlo Tkach 53dcba1189 Update jetty's console build path (#2439) 2024-05-13 16:08:57 +00:00
Pavlo Tkach 3e77004274 Create gcp console service (#2433) 2024-05-10 21:29:58 +00:00
gbrodman fd21fcdb84 Add a GetUserCommand (#2435)
This is fairly simple, similar to most of the other Get*Command classes
2024-05-10 21:25:52 +00:00
gbrodman ae14e35df7 Change a few wording bits in the console (#2436)
These probably aren't perfect but they seemed to make sense given the
old console. Nothing major.
2024-05-10 18:27:55 +00:00
Lai Jiang 94dc9fd0d5 Update GcpJsonFormatter (#2437)
Use the correct JSON field to store the source location info so it can
be parsed by Stackdriver.
2024-05-10 16:47:52 +00:00
gbrodman 7b34659a8f Add registryLockEmailAddress field to User object (#2418)
We've added the field in the database in a previous PR. This is only
used in the old console for now because the new console does not have
registry lock functionality yet
2024-05-09 21:42:45 +00:00
sarahcaseybot 808432e709 Remove the createBillingCost field from Tld (#2425)
* Remove the createBillingCost field from Tld

* fix spacing

* Change field name of map

* Rename getter

* Fix formatting

* Fix todo

* unchange column name
2024-05-08 18:14:03 +00:00
Lai Jiang 73d3b76a89 Remove more usage of AutoValue (#2432)
This PR also removes `SerializedForm` used to serialize
`PendingDeposit`, as it is now a simple record.
2024-05-08 00:50:01 +00:00
Weimin Yu ca072b4861 Add log traces to Nomulus service on GKE (#2427)
* Add log traces to Nomulus service on GKE

Add request-scope log traces to Nomulus on GKE which, unlike
AppEngine and Cloud Run etc, does not generate traces for hosted
applications. This change only affects the GKE image. It does not affect
the AppEngine services.

Log traces are added to Nomulus-generated logs in request-processing
threads. Forked threads are not covered yet. The single relevant use
case (TimeLimiter) will be addressed in a followup PR.

The main change is in the logging configuration:

*  Use gcp-cloud-logging's LoggingHandler

*  Add gcp-cloud-logging's TraceLoggingEnhancer to the handler.

*  Set a thread-local trace id through the TraceLoggingEnhancer in
   ServletBase on request's entry and clear it on completion.

Also removed an unused class (`RequestLogId`).

* CR

* CR
2024-05-07 19:15:46 +00:00
Pavlo Tkach 54c896cbb9 Add console epp password integration (#2426) 2024-05-06 18:32:54 +00:00
Pavlo Tkach 2c7bf2cfdb Update cloudbuild-release.yaml with nokeycheck option (#2431) 2024-05-06 18:01:31 +00:00
gbrodman 49d2e34e12 Add a separate RegistryLock action for the console (#2411)
This handles both GET and POST requests. For POST requests it doesn't
actually change anything about the domains because we will need to add a
verification action (this will be done in a future PR).
2024-05-03 22:37:22 +00:00
Weimin Yu 5511b41f93 Avoid contention over the RefreshDnsRequest table (#2428)
* Avoid contention over the RefreshDnsRequest table

This table can be small at times, when PSQL may use table scan in
queries by keys. At the SERIALIZABLE isolation level, updates to
unrelated rows may conflict due to this `optimization`.

Lower the isolation level to repeatable read.

* Code review
2024-05-03 20:31:54 +00:00
gbrodman 147cdff555 Add registry lock email address col to UserUpdateHistory (#2424) 2024-05-02 15:51:48 +00:00
Ben McIlwain 4b6ade0b14 Bring codebase up to more recent Java standards (#2422)
This includes using the new switch format (though IntelliJ does not yet
understand patterns including default so those aren't used), multiline strings,
replacing some unnecessary type declarations with <>, converting some classes to
records, replacing some Guava predicates with native Java code, and some other
miscellaneous Code Inspection fixes.
2024-05-01 20:48:38 +00:00
Pavlo Tkach 570618705e Allow console access for FTE globar role (#2419) 2024-05-01 16:19:29 +00:00
sarahcaseybot e791608098 Add more indexes to speed up deleteProberDataAction (#2423)
This adds an index on transfer_billing_cancellation_id to Domain and superordinate_domain to Host. When tested on crash with the action limited to only delete 10,000 domains, before these indexes were added the action took about 2 hours to delete 10,000 domains. Once these indexes were added, the action was able to delete the 10,000 domains in a little under 2 minutes.
2024-05-01 15:44:08 +00:00
gbrodman 03b358726a Add Java classes for console history objects (#2350)
This also creates base classes for the objects contained within the
history classes, e.g. RegistrarBase. This is the same way that objects
stored in the HistoryEntry subclasses have base classes, e.g.
DomainBase.
2024-04-30 20:42:40 +00:00
gbrodman d121f8f547 Generate fake XSRF token in FakeConsoleApiParams for tests (#2421) 2024-04-30 17:47:53 +00:00
gbrodman b27218d799 Fix a couple Checkstyle warnings (#2420) 2024-04-29 20:08:53 +00:00
Pavlo Tkach e78ce42dd5 Add console DUM download (#2402)
* Add console DUM download

* Add console DUM download
2024-04-26 15:56:50 +00:00
Ben McIlwain 55fade497d Convert a bunch more @AutoValues to records (#2412) 2024-04-25 16:59:31 +00:00
gbrodman e7501b621a Add DB column for separate rlock email address (#2413)
We cannot rely on the user checking their login email, so we'll want to
send the emails to the other address if configured. This is already the
case in RegistrarPoc.
2024-04-25 15:38:57 +00:00
551 changed files with 13767 additions and 10983 deletions
+2 -5
View File
@@ -47,10 +47,6 @@ war {
if (project.path == ":services:default") {
war {
from("${rootDir}/console-webapp/dist/console-webapp") {
include "**/*"
into("console")
}
from("${coreResourcesDir}/google/registry/ui") {
include "registrar_bin.js"
if (environment != "production") {
@@ -103,10 +99,11 @@ explodeWar.doLast {
file("${it.explodedAppDirectory}/WEB-INF/lib/tools.jar").setWritable(true)
}
appengineDeployAll.mustRunAfter ':console-webapp:deploy'
appengineDeployAll.finalizedBy ':deployCloudSchedulerAndQueue'
rootProject.deploy.dependsOn appengineDeployAll
rootProject.stage.dependsOn appengineStage
tasks['war'].dependsOn ':console-webapp:buildConsoleWebappProd'
tasks['war'].dependsOn ':core:compileProdJS'
tasks['war'].dependsOn ':core:processResources'
tasks['war'].dependsOn ':core:jar'
-2
View File
@@ -539,8 +539,6 @@ task coreDev {
dependsOn 'javadoc'
dependsOn 'checkDependenciesDotGradle'
dependsOn 'checkLicense'
// TODO: @ptkach reenable after console design merged
// dependsOn ':console-webapp:runConsoleWebappUnitTests'
dependsOn ':core:check'
dependsOn 'assemble'
}
+6 -6
View File
@@ -24,7 +24,7 @@ com.google.guava:failureaccess:1.0.2=compileClasspath,deploy_jar,runtimeClasspat
com.google.guava:guava-parent:32.1.1-jre=annotationProcessor,errorprone,testAnnotationProcessor,testingAnnotationProcessor
com.google.guava:guava:31.0.1-jre=checkstyle
com.google.guava:guava:32.1.1-jre=annotationProcessor,errorprone,testAnnotationProcessor,testingAnnotationProcessor
com.google.guava:guava:33.1.0-jre=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath,testing,testingCompileClasspath
com.google.guava:guava:33.2.0-jre=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath,testing,testingCompileClasspath
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=checkstyle,compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath,testing,testingCompileClasspath
com.google.inject:guice:5.1.0=annotationProcessor,errorprone,testAnnotationProcessor,testingAnnotationProcessor
com.google.j2objc:j2objc-annotations:1.3=checkstyle
@@ -54,11 +54,11 @@ org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt
org.jacoco:org.jacoco.core:0.8.11=jacocoAnt
org.jacoco:org.jacoco.report:0.8.11=jacocoAnt
org.javassist:javassist:3.28.0-GA=checkstyle
org.junit.jupiter:junit-jupiter-api:5.10.2=testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-engine:5.10.2=testCompileClasspath,testRuntimeClasspath
org.junit.platform:junit-platform-commons:1.10.2=testCompileClasspath,testRuntimeClasspath
org.junit.platform:junit-platform-engine:1.10.2=testCompileClasspath,testRuntimeClasspath
org.junit:junit-bom:5.10.2=testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-api:5.11.0-M1=testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-engine:5.11.0-M1=testCompileClasspath,testRuntimeClasspath
org.junit.platform:junit-platform-commons:1.11.0-M1=testCompileClasspath,testRuntimeClasspath
org.junit.platform:junit-platform-engine:1.11.0-M1=testCompileClasspath,testRuntimeClasspath
org.junit:junit-bom:5.11.0-M1=testCompileClasspath,testRuntimeClasspath
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath
org.ow2.asm:asm-commons:9.6=jacocoAnt
org.ow2.asm:asm-tree:9.6=jacocoAnt
@@ -175,14 +175,7 @@ public class TextDiffSubject extends Subject {
.orElse(0);
}
private static class SideBySideRowFormatter {
private final int maxExpectedLineLength;
private final int maxActualLineLength;
private SideBySideRowFormatter(int maxExpectedLineLength, int maxActualLineLength) {
this.maxExpectedLineLength = maxExpectedLineLength;
this.maxActualLineLength = maxActualLineLength;
}
private record SideBySideRowFormatter(int maxExpectedLineLength, int maxActualLineLength) {
public String formatRow(String expected, String actual, char padChar) {
return String.format(
@@ -262,6 +262,9 @@
{
"moduleLicense": "Unicode/ICU License"
},
{
"moduleLicense": "Unicode-3.0"
},
{
"moduleLicense": "Public Domain",
"moduleName": "aopalliance:aopalliance"
+17 -6
View File
@@ -100,12 +100,12 @@ PRESUBMITS = {
{"node_modules/"}, REQUIRED):
"Source files must end in a newline.",
# System.(out|err).println should only appear in tools/
# System.(out|err).println should only appear in tools/ or load-testing/
PresubmitCheck(
r".*\bSystem\.(out|err)\.print", "java", {
"StackdriverDashboardBuilder.java", "/tools/", "/example/",
"RegistryTestServerMain.java", "TestServerExtension.java",
"FlowDocumentationTool.java"
"/load-testing/", "RegistryTestServerMain.java",
"TestServerExtension.java", "FlowDocumentationTool.java"
}):
"System.(out|err).println is only allowed in tools/ packages. Please "
"use a logger instead.",
@@ -173,11 +173,11 @@ PRESUBMITS = {
):
"JavaScript files should not include console logging.",
PresubmitCheck(
r".*org\.testcontainers\.shaded.*",
r".*\nimport (static )?.*\.shaded\..*",
"java",
{"/node_modules/"},
):
"Do not use shaded dependencies from testcontainers.",
"Do not use shaded dependencies",
PresubmitCheck(
r".*com\.google\.common\.truth\.Truth8.*",
"java",
@@ -190,7 +190,18 @@ PRESUBMITS = {
{"/node_modules/", "JpaTransactionManagerImpl.java"},
):
"Do not use java.util.Date. Use classes in java.time package instead.",
PresubmitCheck(
r".*com\.google\.api\.client\.http\.HttpStatusCodes.*",
"java",
{"/node_modules/"},
):
"Use status code from jakarta.servlet.http.HttpServletResponse.",
PresubmitCheck(
r".*mock\(Response\.class\).*",
"java",
{"/node_modules/"},
):
"Do not mock Response, use FakeResponse.",
}
# Note that this regex only works for one kind of Flyway file. If we want to
+4
View File
@@ -36,7 +36,11 @@ yarn-error.log
/libpeerconnection.log
testem.log
/typings
.nx/
# System files
.DS_Store
Thumbs.db
# Build artifact
/staged/dist
+9 -3
View File
@@ -11,12 +11,12 @@
// 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.
def consoleDir = "${rootDir}/console-webapp"
def projectParam = "--project=${rootProject.gcpProject}"
clean {
delete "${consoleDir}/node_modules"
delete "${consoleDir}/dist"
delete "${consoleDir}/staged/dist"
}
task npmInstallDeps(type: Exec) {
@@ -62,8 +62,14 @@ task checkFormatting(type: Exec) {
args 'run', 'prettify:check'
}
tasks.runConsoleWebappUnitTests.dependsOn(tasks.npmInstallDeps)
task deploy(type: Exec) {
workingDir "${consoleDir}/staged"
executable 'gcloud'
args 'app', 'deploy', "${projectParam}", '--quiet'
}
tasks.buildConsoleWebappProd.dependsOn(tasks.npmInstallDeps)
tasks.applyFormatting.dependsOn(tasks.npmInstallDeps)
tasks.checkFormatting.dependsOn(tasks.npmInstallDeps)
tasks.build.dependsOn(tasks.checkFormatting)
tasks.deploy.dependsOn(tasks.buildConsoleWebappProd)
+1 -1
View File
@@ -4,7 +4,7 @@
"scripts": {
"ng": "ng",
"start": "ng serve --proxy-config dev-proxy.config.json",
"build": "ng build --base-href=/console/",
"build": "ng build --base-href=/console/ --output-path=staged/dist",
"build:local": "ng build --base-href=/default/console/",
"watch": "ng build --watch --configuration development",
"test": "ng test --browsers=ChromeHeadless --watch=false",
@@ -14,6 +14,7 @@
import { Component, computed } from '@angular/core';
import { RegistrarService } from '../registrar/registrar.service';
import { MatSnackBar } from '@angular/material/snack-bar';
@Component({
selector: 'app-billingInfo',
@@ -22,20 +23,25 @@ import { RegistrarService } from '../registrar/registrar.service';
})
export class BillingInfoComponent {
public static PATH = 'billingInfo';
constructor(public registrarService: RegistrarService) {}
constructor(
public registrarService: RegistrarService,
private _snackBar: MatSnackBar
) {}
driveFolderUrl = computed<string>(() => {
if (this.registrarService.registrar()?.driveFolderId) {
return `https://drive.google.com/drive/folders/${
return (
'https://drive.google.com/drive/folders/' +
this.registrarService.registrar()?.driveFolderId
}`;
);
}
return '';
});
openBillingDetails(e: MouseEvent) {
if (!this.driveFolderUrl()) {
if (!this.registrarService.registrar()?.driveFolderId) {
e.preventDefault();
this._snackBar.open('Billing Folder ID has not been assigned');
}
}
}
@@ -1,6 +1,6 @@
<app-selected-registrar-wrapper>
<h1 class="mat-headline-4">Domains</h1>
<div class="console-domains">
<h1 class="mat-headline-4">Domains</h1>
@if (totalResults === 0) {
<div class="console-app__empty-domains">
<h1>
@@ -13,6 +13,17 @@
} @else if(isLoading) {
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
} @else {
<a
mat-stroked-button
color="primary"
href="/console-api/dum-download?registrarId={{
registrarService.registrarId()
}}"
class="console-app-domains__download"
>
<mat-icon>download</mat-icon>
Download domains (.csv)
</a>
<mat-form-field class="console-app__domains-filter">
<mat-label>Filter</mat-label>
<input
@@ -12,6 +12,15 @@
}
}
&-domains {
position: relative;
&__download {
position: absolute;
top: 0;
right: 0;
}
}
&__domains {
width: 100%;
overflow: auto;
@@ -54,11 +54,13 @@ export class DomainListComponent {
constructor(
private backendService: BackendService,
private domainListService: DomainListService,
private registrarService: RegistrarService,
protected registrarService: RegistrarService,
private _snackBar: MatSnackBar
) {
effect(() => {
if (this.registrarService.registrarId()) {
this.pageNumber = 0;
this.totalResults = 0;
this.reloadData();
}
});
@@ -10,7 +10,7 @@
<mat-icon class="secondary-text">view_list</mat-icon>
DUMs
</h3>
<p class="secondary-text">View Domains</p>
<p class="secondary-text">View Domains Under Management</p>
</mat-card-content>
<mat-card-actions>
<button mat-button color="primary" (click)="viewDums()">
@@ -7,7 +7,7 @@
*matTreeNodeDef="let node"
matTreeNodeToggle
(click)="onClick(node)"
[class.active]="router.url.endsWith(node.path)"
[class.active]="router.url.includes(node.path)"
>
<mat-icon class="console-app__nav-icon" *ngIf="node.iconName">
{{ node.iconName }}
@@ -26,7 +26,7 @@
}
&-driveId {
min-width: 200px;
word-break: break-all;
word-break: break-word;
}
&-registryLockAllowed {
max-width: 80px;
@@ -51,10 +51,12 @@ export const columns = [
columnDef: 'billingAccountMap',
header: 'Billing Accounts',
cell: (record: Registrar) =>
// @ts-ignore - completely legit line, but TS keeps complaining
`${Object.entries(record.billingAccountMap).reduce((acc, [key, val]) => {
return `${acc}${key}=${val}<br/>`;
}, '')}`,
`${Object.entries(record.billingAccountMap || {}).reduce(
(acc, [key, val]) => {
return `${acc}${key}=${val}<br/>`;
},
''
)}`,
},
{
columnDef: 'registryLockAllowed',
@@ -1,4 +1,4 @@
<h1 class="mat-headline-4">Resource</h1>
<h1 class="mat-headline-4">Resources</h1>
<div class="console-app__resources">
<div>
<div class="console-app__resources-subhead">Technical resources</div>
@@ -6,7 +6,8 @@
class="text-l"
href="{{ userDataService.userData.technicalDocsUrl }}"
target="_blank"
>View on Google Drive</a
>View onboarding FAQs, TLD information, and technical documentation on
Google Drive</a
>
</div>
<div>
@@ -71,7 +71,7 @@ export default class ContactComponent {
effect(() => {
if (this.contactService.contacts()) {
this.dataSource = new MatTableDataSource<ViewReadyContact>(
this.contactService.contacts().map(contactTypeToViewReadyContact)
this.contactService.contacts()
);
}
});
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { HttpErrorResponse } from '@angular/common/http';
import { Component } from '@angular/core';
import {
AbstractControl,
@@ -68,9 +69,12 @@ export default class EppPasswordEditComponent {
) {
this.passwordUpdateForm?.get('newPasswordRepeat')?.setErrors(null);
} else {
this.passwordUpdateForm
?.get('newPasswordRepeat')
?.setErrors({ passwordsDontMatch: control.value });
// latest angular just won't detect the error without setTimeout
setTimeout(() => {
this.passwordUpdateForm
?.get('newPasswordRepeat')
?.setErrors({ passwordsDontMatch: control.value });
});
}
return null;
};
@@ -92,15 +96,24 @@ export default class EppPasswordEditComponent {
});
save() {
debugger;
// this.securityService.saveEppPassword().subscribe({
// complete: () => {
// this.goBack();
// },
// error: (err: HttpErrorResponse) => {
// this._snackBar.open(err.error);
// },
// });
const { oldPassword, newPassword, newPasswordRepeat } =
this.passwordUpdateForm.value;
if (!oldPassword || !newPassword || !newPasswordRepeat) return;
this.securityService
.saveEppPassword({
registrarId: this.registrarService.registrarId(),
oldPassword,
newPassword,
newPasswordRepeat,
})
.subscribe({
complete: () => {
this.goBack();
},
error: (err: HttpErrorResponse) => {
this._snackBar.open(err.error);
},
});
}
goBack() {
@@ -24,7 +24,7 @@
</mat-list-item>
<mat-list-item role="listitem" lines="3">
<span class="console-app__list-value"
>todo: come up with a text here</span
>Change the password used for EPP logins</span
>
</mat-list-item>
<mat-list-item role="listitem">
@@ -22,6 +22,13 @@ import {
} from 'src/app/registrar/registrar.service';
import { BackendService } from 'src/app/shared/services/backend.service';
export interface EppPasswordBackendModel {
registrarId: string;
oldPassword: string;
newPassword: string;
newPasswordRepeat: string;
}
export function apiToUiConverter(
securitySettings: SecuritySettingsBackendModel = {}
): SecuritySettings {
@@ -68,5 +75,11 @@ export class SecurityService {
);
}
saveEppPassword() {}
saveEppPassword(data: EppPasswordBackendModel) {
return this.backend.postEppPasswordUpdate(data).pipe(
switchMap(() => {
return this.registrarService.loadRegistrars();
})
);
}
}
@@ -37,7 +37,7 @@ export default class WhoisComponent {
result += `${registrar?.localizedAddress?.state} `;
}
if (registrar?.localizedAddress?.countryCode) {
result += registrar?.localizedAddress?.countryCode;
result += `${registrar?.localizedAddress?.countryCode} `;
}
if (registrar?.localizedAddress?.zip) {
result += registrar?.localizedAddress?.zip;
@@ -23,6 +23,7 @@ import {
WhoisRegistrarFields,
} from '../../registrar/registrar.service';
import { Contact } from '../../settings/contact/contact.service';
import { EppPasswordBackendModel } from '../../settings/security/security.service';
import { UserData } from './userData.service';
@Injectable()
@@ -33,6 +34,11 @@ export class BackendService {
error: HttpErrorResponse,
mockData?: Type
): Observable<Type> {
// This is a temporary redirect to the old console until the new console
// is fully released and enabled
if (error.url && new URL(error.url).pathname === '/registrar') {
window.location.href = error.url;
}
if (error.error instanceof Error) {
// A client-side or network error occurred. Handle it accordingly.
console.error('An error occurred:', error.error.message);
@@ -134,6 +140,15 @@ export class BackendService {
);
}
postEppPasswordUpdate(
data: EppPasswordBackendModel
): Observable<EppPasswordBackendModel> {
return this.http.post<EppPasswordBackendModel>(
`/console-api/eppPassword`,
data
);
}
getUserData(): Observable<UserData> {
return this.http
.get<UserData>('/console-api/userdata')
@@ -30,7 +30,7 @@ export interface GlobalLoader {
providedIn: 'root',
})
export class GlobalLoaderService {
private static readonly TIMEOUT_MS = 3000;
private static readonly TIMEOUT_MS = 10000;
private loaders = new Map<GlobalLoader, Subscription>();
public isLoading: boolean = false;
+1 -1
View File
@@ -63,7 +63,7 @@ body {
.console-app__list-value {
font-size: 14px;
white-space: pre-line;
word-break: break-all;
word-break: break-word;
color: var(--text);
}
}
+4
View File
@@ -0,0 +1,4 @@
runtime: nodejs20
service: console
build_env_variables:
GOOGLE_NODE_RUN_SCRIPTS: ''
+12
View File
@@ -0,0 +1,12 @@
{
"name": "console-webapp-static-server",
"version": "0.0.0",
"scripts": {
"start": "node server.js",
"gcp-build":""
},
"private": true,
"dependencies": {
"express": "^4.16.4"
}
}
@@ -1,4 +1,4 @@
// Copyright 2021 The Nomulus Authors. All Rights Reserved.
// Copyright 2024 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.
@@ -12,9 +12,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.model.annotations;
const express = require('express');
/**
* Annotation to indicate a class that should be deleted after the database migration is complete.
*/
public @interface DeleteAfterMigration {}
const app = express();
const PORT = process.env.PORT || 8080;
app.use("/console", express.static('dist', {
etag: false,
lastModified: false,
maxAge: '1d',
setHeaders: setCustomCacheControl
}));
function setCustomCacheControl (res, path) {
// Custom Cache-Control for HTML files - we don't want to cache them
if (express.static.mime.lookup(path) === 'text/html') {
res.setHeader('Cache-Control', 'public, max-age=0');
}
}
app.listen(PORT);
-6
View File
@@ -153,7 +153,6 @@ dependencies {
implementation deps['com.google.apis:google-api-services-monitoring']
implementation deps['com.google.apis:google-api-services-sheets']
implementation deps['com.google.apis:google-api-services-storage']
testImplementation deps['com.google.appengine:appengine-api-stubs']
implementation deps['com.google.auth:google-auth-library-credentials']
implementation deps['com.google.auth:google-auth-library-oauth2-http']
implementation deps['com.google.cloud.bigdataoss:util']
@@ -250,10 +249,6 @@ dependencies {
implementation deps['us.fatehi:schemacrawler-tools']
implementation deps['xerces:xmlParserAPIs']
implementation deps['org.ogce:xpp3']
// This dependency must come after javax.mail:mail as it would otherwise
// shadow classes in package javax.mail with its own implementation.
implementation deps['com.google.appengine:appengine-api-1.0-sdk']
// Known issue: nebula-lint misses inherited dependency.
implementation project(':common')
testImplementation project(path: ':common', configuration: 'testing')
@@ -271,7 +266,6 @@ dependencies {
testAnnotationProcessor project(':processor')
testImplementation deps['com.google.cloud:google-cloud-nio']
testImplementation deps['com.google.appengine:appengine-testing']
testImplementation deps['com.google.guava:guava-testlib']
testImplementation deps['com.google.monitoring-client:contrib']
testImplementation deps['com.google.protobuf:protobuf-java-util']
+174 -166
View File
@@ -8,14 +8,22 @@ args4j:args4j:2.0.26=css
args4j:args4j:2.33=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
cglib:cglib-nodep:2.2=css
com.charleskorn.kaml:kaml:0.20.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
com.fasterxml.jackson.core:jackson-annotations:2.16.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.fasterxml.jackson.core:jackson-core:2.16.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.fasterxml.jackson.core:jackson-databind:2.16.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.fasterxml.jackson.dataformat:jackson-dataformat-toml:2.16.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.16.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.fasterxml.jackson.datatype:jackson-datatype-joda:2.16.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.16.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.fasterxml.jackson:jackson-bom:2.16.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.fasterxml.jackson.core:jackson-annotations:2.16.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
com.fasterxml.jackson.core:jackson-annotations:2.17.0=testCompileClasspath,testRuntimeClasspath
com.fasterxml.jackson.core:jackson-core:2.16.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
com.fasterxml.jackson.core:jackson-core:2.17.0=testCompileClasspath,testRuntimeClasspath
com.fasterxml.jackson.core:jackson-databind:2.16.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
com.fasterxml.jackson.core:jackson-databind:2.17.0=testCompileClasspath,testRuntimeClasspath
com.fasterxml.jackson.dataformat:jackson-dataformat-toml:2.16.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
com.fasterxml.jackson.dataformat:jackson-dataformat-toml:2.17.0=testCompileClasspath,testRuntimeClasspath
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.16.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.17.0=testCompileClasspath,testRuntimeClasspath
com.fasterxml.jackson.datatype:jackson-datatype-joda:2.16.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
com.fasterxml.jackson.datatype:jackson-datatype-joda:2.17.0=testCompileClasspath,testRuntimeClasspath
com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.16.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.0=testCompileClasspath,testRuntimeClasspath
com.fasterxml.jackson:jackson-bom:2.16.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
com.fasterxml.jackson:jackson-bom:2.17.0=testCompileClasspath,testRuntimeClasspath
com.fasterxml:classmate:1.5.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.github.ben-manes.caffeine:caffeine:3.0.5=annotationProcessor,errorprone,nonprodAnnotationProcessor,testAnnotationProcessor
com.github.ben-manes.caffeine:caffeine:3.1.8=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
@@ -32,72 +40,71 @@ com.github.jnr:jnr-unixsocket:0.38.22=compileClasspath,deploy_jar,nonprodCompile
com.github.jnr:jnr-x86asm:1.0.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.github.kevinstern:software-and-algorithms:1.0=annotationProcessor,errorprone,nonprodAnnotationProcessor,testAnnotationProcessor
com.google.android:annotations:4.1.1.4=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
com.google.api-client:google-api-client-appengine:2.4.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api-client:google-api-client-appengine:2.5.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api-client:google-api-client-jackson2:2.0.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api-client:google-api-client-java6:2.1.4=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api-client:google-api-client-servlet:2.4.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api-client:google-api-client-servlet:2.5.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api-client:google-api-client:1.35.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:gapic-google-cloud-storage-v2:2.32.1-alpha=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1:3.1.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.173.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta2:0.173.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-bigtable-v2:2.33.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-pubsub-v1:1.108.5=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-pubsublite-v1:1.12.22=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-spanner-admin-database-v1:6.58.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-spanner-admin-instance-v1:6.58.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-spanner-v1:6.58.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-storage-v2:2.32.1-alpha=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-common-protos:2.37.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1:3.1.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1beta1:0.173.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1beta2:0.173.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-bigtable-admin-v2:2.33.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-bigtable-v2:2.33.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-datastore-v1:0.109.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-firestore-v1:3.16.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:gapic-google-cloud-storage-v2:2.32.1-alpha=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
com.google.api.grpc:gapic-google-cloud-storage-v2:2.38.0-alpha=testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1:3.4.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.176.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta2:0.176.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-bigtable-v2:2.37.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-pubsub-v1:1.109.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-pubsublite-v1:1.13.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-spanner-admin-database-v1:6.62.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-spanner-admin-instance-v1:6.62.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-spanner-v1:6.62.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-cloud-storage-v2:2.32.1-alpha=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
com.google.api.grpc:grpc-google-cloud-storage-v2:2.38.0-alpha=testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:grpc-google-common-protos:2.39.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1:3.4.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1beta1:0.176.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1beta2:0.176.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-bigtable-admin-v2:2.37.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-bigtable-v2:2.37.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-datastore-v1:0.110.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-firestore-v1:3.20.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-monitoring-v3:1.64.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
com.google.api.grpc:proto-google-cloud-monitoring-v3:3.36.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-pubsub-v1:1.108.5=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-pubsublite-v1:1.12.22=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-secretmanager-v1:2.41.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-secretmanager-v1beta2:2.41.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-spanner-admin-database-v1:6.58.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-spanner-admin-instance-v1:6.58.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-spanner-executor-v1:6.58.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-spanner-v1:6.58.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-storage-v2:2.32.1-alpha=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-tasks-v2:2.41.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-tasks-v2beta2:0.131.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-tasks-v2beta3:0.131.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-common-protos:2.37.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-iam-v1:1.32.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api:api-common:2.29.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api:gax-grpc:2.46.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api:gax-httpjson:2.46.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api:gax:2.46.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-admin-directory:directory_v1-rev20240304-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-appengine:v1-rev20240226-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-bigquery:v2-rev20240124-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-cloudresourcemanager:v1-rev20240128-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-dataflow:v1b3-rev20240113-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-monitoring-v3:3.39.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-pubsub-v1:1.109.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-pubsublite-v1:1.13.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-secretmanager-v1:2.43.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-secretmanager-v1beta2:2.43.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-spanner-admin-database-v1:6.62.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-spanner-admin-instance-v1:6.62.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-spanner-executor-v1:6.62.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-spanner-v1:6.62.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-storage-v2:2.32.1-alpha=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
com.google.api.grpc:proto-google-cloud-storage-v2:2.38.0-alpha=testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-tasks-v2:2.43.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-tasks-v2beta2:0.133.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-cloud-tasks-v2beta3:0.133.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-common-protos:2.39.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-iam-v1:1.34.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api:api-common:2.31.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api:gax-grpc:2.48.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api:gax-httpjson:2.48.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api:gax:2.48.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-admin-directory:directory_v1-rev20240509-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-appengine:v1-rev20240415-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-bigquery:v2-rev20240229-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-cloudresourcemanager:v1-rev20240310-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-dataflow:v1b3-rev20240218-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-dns:v2beta1-rev99-1.25.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-drive:v2-rev393-1.25.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-gmail:v1-rev20231218-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-gmail:v1-rev20240422-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-groupssettings:v1-rev20210624-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-healthcare:v1-rev20240130-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-iam:v2-rev20240314-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-iamcredentials:v1-rev20211203-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-monitoring:v3-rev20240414-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-monitoring:v3-rev20240427-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-pubsub:v1-rev20220904-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-sheets:v4-rev20240402-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-sheets:v4-rev20240423-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-sqladmin:v1beta4-rev20240324-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-storage:v1-rev20240205-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.appengine:appengine-api-1.0-sdk:2.0.26=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.appengine:appengine-api-stubs:2.0.26=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.appengine:appengine-remote-api:2.0.26=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.appengine:appengine-testing:2.0.26=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.appengine:appengine-tools-sdk:2.0.26=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.apis:google-api-services-storage:v1-rev20240311-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
com.google.apis:google-api-services-storage:v1-rev20240319-2.0.0=testCompileClasspath,testRuntimeClasspath
com.google.auth:google-auth-library-credentials:1.23.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.auth:google-auth-library-oauth2-http:1.23.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.auto.service:auto-service-annotations:1.0.1=errorprone,nonprodAnnotationProcessor,testAnnotationProcessor
@@ -111,27 +118,31 @@ com.google.closure-stylesheets:closure-stylesheets:1.5.0=css
com.google.cloud.bigdataoss:gcsio:2.2.16=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud.bigdataoss:util:2.2.16=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud.bigtable:bigtable-client-core-config:1.28.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud.datastore:datastore-v1-proto-client:2.18.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud.datastore:datastore-v1-proto-client:2.19.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud.sql:jdbc-socket-factory-core:1.18.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud.sql:postgres-socket-factory:1.18.0=deploy_jar,runtimeClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-bigquerystorage:3.1.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-bigtable-stats:2.33.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-bigtable:2.33.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-core-grpc:2.32.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-core-http:2.31.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-core:2.32.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-firestore:3.16.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-bigquerystorage:3.4.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-bigtable-stats:2.37.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-bigtable:2.37.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-core-grpc:2.36.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
com.google.cloud:google-cloud-core-grpc:2.38.0=testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-core-http:2.31.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
com.google.cloud:google-cloud-core-http:2.38.0=testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-core:2.36.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
com.google.cloud:google-cloud-core:2.38.0=testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-firestore:3.20.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-monitoring:1.82.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
com.google.cloud:google-cloud-monitoring:3.36.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-nio:0.127.15=testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-pubsub:1.126.5=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-pubsublite:1.12.22=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-secretmanager:2.41.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-spanner:6.58.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-storage:2.32.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-tasks:2.41.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-monitoring:3.39.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-nio:0.127.17=testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-pubsub:1.127.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-pubsublite:1.13.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-secretmanager:2.43.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-spanner:6.62.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-storage:2.32.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
com.google.cloud:google-cloud-storage:2.38.0=testCompileClasspath,testRuntimeClasspath
com.google.cloud:google-cloud-tasks:2.43.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:grpc-gcp:1.5.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:proto-google-cloud-firestore-bundle-v1:3.16.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.cloud:proto-google-cloud-firestore-bundle-v1:3.20.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.code.findbugs:jsr305:3.0.1=css
com.google.code.findbugs:jsr305:3.0.2=annotationProcessor,checkstyle,compileClasspath,deploy_jar,errorprone,nonprodAnnotationProcessor,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,soy,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath
com.google.code.gson:gson:2.10.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
@@ -159,19 +170,21 @@ com.google.googlejavaformat:google-java-format:1.5=annotationProcessor,testAnnot
com.google.guava:failureaccess:1.0.1=checkstyle,errorprone,nonprodAnnotationProcessor,soy
com.google.guava:failureaccess:1.0.2=annotationProcessor,compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath
com.google.guava:guava-parent:32.1.1-jre=errorprone,nonprodAnnotationProcessor
com.google.guava:guava-testlib:33.1.0-jre=testCompileClasspath,testRuntimeClasspath
com.google.guava:guava-testlib:33.2.0-jre=testCompileClasspath,testRuntimeClasspath
com.google.guava:guava:20.0=css
com.google.guava:guava:31.0.1-jre=checkstyle,soy
com.google.guava:guava:32.1.1-jre=errorprone,nonprodAnnotationProcessor
com.google.guava:guava:33.0.0-jre=annotationProcessor,testAnnotationProcessor
com.google.guava:guava:33.1.0-jre=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.guava:guava:33.1.0-jre=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
com.google.guava:guava:33.2.0-jre=testCompileClasspath,testRuntimeClasspath
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=annotationProcessor,checkstyle,compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,soy,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath
com.google.gwt:gwt-user:2.10.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.http-client:google-http-client-apache-v2:1.43.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.http-client:google-http-client-apache-v2:1.43.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
com.google.http-client:google-http-client-apache-v2:1.44.1=testCompileClasspath,testRuntimeClasspath
com.google.http-client:google-http-client-appengine:1.44.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.http-client:google-http-client-gson:1.44.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.http-client:google-http-client-jackson2:1.43.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.http-client:google-http-client-protobuf:1.43.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.http-client:google-http-client-jackson2:1.44.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.http-client:google-http-client-protobuf:1.44.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.http-client:google-http-client:1.44.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.inject.extensions:guice-multibindings:4.1.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,soy,testCompileClasspath,testRuntimeClasspath
com.google.inject:guice:4.1.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
@@ -187,16 +200,16 @@ com.google.jsinterop:jsinterop-annotations:2.0.0=compileClasspath,deploy_jar,non
com.google.monitoring-client:contrib:1.0.7=testCompileClasspath,testRuntimeClasspath
com.google.monitoring-client:metrics:1.0.7=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.monitoring-client:stackdriver:1.0.7=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.oauth-client:google-oauth-client-appengine:1.35.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.oauth-client:google-oauth-client-java6:1.35.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.oauth-client:google-oauth-client-jetty:1.35.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.oauth-client:google-oauth-client-servlet:1.35.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.oauth-client:google-oauth-client:1.35.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.protobuf:protobuf-java-util:3.25.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.oauth-client:google-oauth-client-appengine:1.36.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.oauth-client:google-oauth-client-java6:1.36.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.oauth-client:google-oauth-client-jetty:1.36.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.oauth-client:google-oauth-client-servlet:1.36.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.oauth-client:google-oauth-client:1.36.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.protobuf:protobuf-java-util:3.25.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.protobuf:protobuf-java:2.5.0=css
com.google.protobuf:protobuf-java:3.13.0=soy
com.google.protobuf:protobuf-java:3.19.6=annotationProcessor,errorprone,nonprodAnnotationProcessor,testAnnotationProcessor
com.google.protobuf:protobuf-java:3.25.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.protobuf:protobuf-java:3.25.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.re2j:re2j:1.7=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.template:soy:2021-02-01=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,soy,testCompileClasspath,testRuntimeClasspath
com.google.truth:truth:1.4.2=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
@@ -233,11 +246,11 @@ com.sun.xml.bind:jaxb-impl:2.3.9=jaxb
com.sun.xml.bind:jaxb-osgi:4.0.5=jaxb
com.sun.xml.bind:jaxb-xjc:2.3.9=jaxb
com.sun.xml.fastinfoset:FastInfoset:1.2.15=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.thoughtworks.paranamer:paranamer:2.7=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.zaxxer:HikariCP:5.1.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
commons-beanutils:commons-beanutils:1.9.4=checkstyle
commons-codec:commons-codec:1.16.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
commons-collections:commons-collections:3.2.2=checkstyle
commons-io:commons-io:2.16.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
commons-logging:commons-logging:1.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
dnsjava:dnsjava:3.5.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
guru.nidi.com.eclipsesource.j2v8:j2v8_linux_x86_64:4.6.0=testRuntimeClasspath
@@ -255,24 +268,21 @@ io.github.java-diff-utils:java-diff-utils:4.12=annotationProcessor,deploy_jar,er
io.grpc:grpc-alts:1.62.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.grpc:grpc-api:1.62.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.grpc:grpc-auth:1.62.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.grpc:grpc-census:1.61.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.grpc:grpc-census:1.62.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.grpc:grpc-context:1.62.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.grpc:grpc-core:1.62.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.grpc:grpc-googleapis:1.62.2=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
io.grpc:grpc-grpclb:1.62.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.grpc:grpc-inprocess:1.62.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.grpc:grpc-netty-shaded:1.62.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.grpc:grpc-netty:1.61.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.grpc:grpc-netty:1.62.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.grpc:grpc-protobuf-lite:1.62.2=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
io.grpc:grpc-protobuf:1.62.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.grpc:grpc-rls:1.61.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
io.grpc:grpc-services:1.61.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
io.grpc:grpc-services:1.62.2=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
io.grpc:grpc-rls:1.62.2=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
io.grpc:grpc-services:1.62.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.grpc:grpc-stub:1.62.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.grpc:grpc-util:1.61.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
io.grpc:grpc-util:1.62.2=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
io.grpc:grpc-xds:1.61.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
io.grpc:grpc-xds:1.62.2=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
io.grpc:grpc-util:1.62.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.grpc:grpc-xds:1.62.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.netty:netty-buffer:4.1.100.Final=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.netty:netty-codec-http2:4.1.100.Final=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
io.netty:netty-codec-http:4.1.100.Final=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
@@ -325,41 +335,41 @@ javax.xml.bind:jaxb-api:2.4.0-b180830.0359=jaxb
joda-time:joda-time:2.10.14=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
junit:junit:4.13.2=nonprodCompileClasspath,nonprodRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
net.arnx:nashorn-promise:0.1.1=testRuntimeClasspath
net.bytebuddy:byte-buddy-agent:1.14.12=testCompileClasspath,testRuntimeClasspath
net.bytebuddy:byte-buddy:1.12.18=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
net.bytebuddy:byte-buddy:1.14.12=testCompileClasspath,testRuntimeClasspath
net.bytebuddy:byte-buddy-agent:1.14.15=testCompileClasspath,testRuntimeClasspath
net.bytebuddy:byte-buddy:1.14.12=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
net.bytebuddy:byte-buddy:1.14.15=testCompileClasspath,testRuntimeClasspath
net.java.dev.javacc:javacc:4.1=css
net.java.dev.jna:jna:5.13.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
net.ltgt.gradle.incap:incap:0.2=annotationProcessor,testAnnotationProcessor
net.sf.saxon:Saxon-HE:10.6=checkstyle
org.antlr:antlr4-runtime:4.7=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.antlr:antlr4-runtime:4.9.3=checkstyle
org.apache.arrow:arrow-format:15.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.arrow:arrow-memory-core:15.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.arrow:arrow-vector:15.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.avro:avro:1.8.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-model-fn-execution:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-model-job-management:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-model-pipeline:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.arrow:arrow-format:15.0.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.arrow:arrow-memory-core:15.0.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.arrow:arrow-vector:15.0.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.avro:avro:1.11.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-model-fn-execution:2.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-model-job-management:2.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-model-pipeline:2.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-runners-core-construction-java:2.54.0=testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-runners-core-java:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-runners-direct-java:2.55.1=testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-runners-google-cloud-dataflow-java:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-runners-java-fn-execution:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-core:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-expansion-service:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-extensions-arrow:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-extensions-avro:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-extensions-protobuf:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-runners-core-java:2.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-runners-direct-java:2.56.0=testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-runners-google-cloud-dataflow-java:2.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-runners-java-fn-execution:2.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-core:2.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-expansion-service:2.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-extensions-arrow:2.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-extensions-avro:2.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core:2.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-extensions-protobuf:2.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-fn-execution:2.54.0=testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-harness:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-io-google-cloud-platform:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-transform-service-launcher:2.55.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-harness:2.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-io-google-cloud-platform:2.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-sdks-java-transform-service-launcher:2.56.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-vendor-grpc-1_60_1:0.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.beam:beam-vendor-guava-32_1_2-jre:0.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.commons:commons-compress:1.24.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.commons:commons-csv:1.10.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.commons:commons-csv:1.11.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apache.commons:commons-exec:1.3=testCompileClasspath,testRuntimeClasspath
org.apache.commons:commons-lang3:3.14.0=testCompileClasspath,testRuntimeClasspath
org.apache.commons:commons-lang3:3.9=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
@@ -373,12 +383,12 @@ org.apache.sshd:sshd-common:2.12.1=testCompileClasspath,testRuntimeClasspath
org.apache.sshd:sshd-core:2.12.1=testCompileClasspath,testRuntimeClasspath
org.apache.sshd:sshd-scp:2.12.1=testCompileClasspath,testRuntimeClasspath
org.apache.sshd:sshd-sftp:2.12.1=testCompileClasspath,testRuntimeClasspath
org.apache.tomcat:tomcat-annotations-api:11.0.0-M19=testCompileClasspath,testRuntimeClasspath
org.apache.tomcat:tomcat-annotations-api:11.0.0-M20=testCompileClasspath,testRuntimeClasspath
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath
org.bouncycastle:bcpg-jdk18on:1.78=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.bouncycastle:bcpkix-jdk18on:1.78=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.bouncycastle:bcprov-jdk18on:1.78=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.bouncycastle:bcutil-jdk18on:1.78=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.bouncycastle:bcpg-jdk18on:1.78.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.bouncycastle:bcpkix-jdk18on:1.78.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.bouncycastle:bcprov-jdk18on:1.78.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.bouncycastle:bcutil-jdk18on:1.78.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.checkerframework:checker-compat-qual:2.5.3=compileClasspath,nonprodCompileClasspath,testCompileClasspath
org.checkerframework:checker-compat-qual:2.5.5=annotationProcessor,testAnnotationProcessor
org.checkerframework:checker-compat-qual:2.5.6=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
@@ -386,24 +396,23 @@ org.checkerframework:checker-qual:3.12.0=checkstyle,soy
org.checkerframework:checker-qual:3.33.0=errorprone,nonprodAnnotationProcessor
org.checkerframework:checker-qual:3.41.0=annotationProcessor,testAnnotationProcessor
org.checkerframework:checker-qual:3.42.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.codehaus.jackson:jackson-core-asl:1.9.13=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.codehaus.jackson:jackson-mapper-asl:1.9.13=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.codehaus.mojo:animal-sniffer-annotations:1.23=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
org.conscrypt:conscrypt-openjdk-uber:2.5.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.easymock:easymock:3.0=css
org.eclipse.collections:eclipse-collections-api:11.1.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.eclipse.collections:eclipse-collections:11.1.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty.ee10:jetty-ee10-servlet:12.0.8=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty.ee10:jetty-ee10-webapp:12.0.8=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-http:12.0.8=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-io:12.0.8=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-security:12.0.8=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-server:12.0.8=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-session:12.0.8=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-util:12.0.8=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-xml:12.0.8=testCompileClasspath,testRuntimeClasspath
org.flywaydb:flyway-core:10.11.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.flywaydb:flyway-database-postgresql:10.11.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty.ee10:jetty-ee10-servlet:12.0.9=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty.ee10:jetty-ee10-webapp:12.0.9=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-ee:12.0.9=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-http:12.0.9=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-io:12.0.9=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-security:12.0.9=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-server:12.0.9=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-session:12.0.9=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-util:12.0.9=testCompileClasspath,testRuntimeClasspath
org.eclipse.jetty:jetty-xml:12.0.9=testCompileClasspath,testRuntimeClasspath
org.flywaydb:flyway-core:10.13.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.flywaydb:flyway-database-postgresql:10.13.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.glassfish.jaxb:jaxb-runtime:2.3.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.glassfish.jaxb:txw2:2.3.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.gwtproject:gwt-user:2.10.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
@@ -442,27 +451,27 @@ org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.0.1=deploy_jar,nonprodRun
org.jetbrains.kotlinx:kotlinx-serialization-core:1.0.1=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
org.jetbrains:annotations:13.0=annotationProcessor,testAnnotationProcessor
org.jetbrains:annotations:17.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.jline:jline:3.25.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.jline:jline:3.26.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.joda:joda-money:1.0.4=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.json:json:20160212=soy
org.json:json:20231013=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.json:json:20240303=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.jsoup:jsoup:1.17.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.junit-pioneer:junit-pioneer:2.2.0=testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-api:5.10.2=testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-engine:5.10.2=testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-migrationsupport:5.10.2=testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-params:5.10.2=testCompileClasspath,testRuntimeClasspath
org.junit.platform:junit-platform-commons:1.10.2=testCompileClasspath,testRuntimeClasspath
org.junit.platform:junit-platform-engine:1.10.2=testCompileClasspath,testRuntimeClasspath
org.junit.platform:junit-platform-launcher:1.10.2=testCompileClasspath,testRuntimeClasspath
org.junit.platform:junit-platform-runner:1.10.2=testCompileClasspath,testRuntimeClasspath
org.junit.platform:junit-platform-suite-api:1.10.2=testCompileClasspath,testRuntimeClasspath
org.junit.platform:junit-platform-suite-commons:1.10.2=testRuntimeClasspath
org.junit:junit-bom:5.10.2=testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-api:5.11.0-M1=testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-engine:5.11.0-M1=testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-migrationsupport:5.11.0-M1=testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-params:5.11.0-M1=testCompileClasspath,testRuntimeClasspath
org.junit.platform:junit-platform-commons:1.11.0-M1=testCompileClasspath,testRuntimeClasspath
org.junit.platform:junit-platform-engine:1.11.0-M1=testCompileClasspath,testRuntimeClasspath
org.junit.platform:junit-platform-launcher:1.11.0-M1=testCompileClasspath,testRuntimeClasspath
org.junit.platform:junit-platform-runner:1.11.0-M1=testCompileClasspath,testRuntimeClasspath
org.junit.platform:junit-platform-suite-api:1.11.0-M1=testCompileClasspath,testRuntimeClasspath
org.junit.platform:junit-platform-suite-commons:1.11.0-M1=testRuntimeClasspath
org.junit:junit-bom:5.11.0-M1=testCompileClasspath,testRuntimeClasspath
org.jvnet.staxex:stax-ex:1.8=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.mockito:mockito-core:1.10.19=css
org.mockito:mockito-core:5.11.0=testCompileClasspath,testRuntimeClasspath
org.mockito:mockito-junit-jupiter:5.11.0=testCompileClasspath,testRuntimeClasspath
org.mockito:mockito-core:5.12.0=testCompileClasspath,testRuntimeClasspath
org.mockito:mockito-junit-jupiter:5.12.0=testCompileClasspath,testRuntimeClasspath
org.objenesis:objenesis:2.1=css
org.objenesis:objenesis:3.3=testRuntimeClasspath
org.ogce:xpp3:1.1.6=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
@@ -499,14 +508,13 @@ org.slf4j:slf4j-api:2.0.13=compileClasspath,nonprodCompileClasspath,nonprodRunti
org.slf4j:slf4j-api:2.1.0-alpha1=deploy_jar,runtimeClasspath,testRuntimeClasspath
org.slf4j:slf4j-jdk14:2.1.0-alpha1=deploy_jar,runtimeClasspath,testRuntimeClasspath
org.snakeyaml:snakeyaml-engine:2.1=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
org.testcontainers:database-commons:1.19.7=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.testcontainers:jdbc:1.19.7=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.testcontainers:junit-jupiter:1.19.7=testCompileClasspath,testRuntimeClasspath
org.testcontainers:postgresql:1.19.7=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.testcontainers:selenium:1.19.7=testCompileClasspath,testRuntimeClasspath
org.testcontainers:testcontainers:1.19.7=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.threeten:threetenbp:1.6.8=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.tukaani:xz:1.5=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.testcontainers:database-commons:1.19.8=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.testcontainers:jdbc:1.19.8=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.testcontainers:junit-jupiter:1.19.8=testCompileClasspath,testRuntimeClasspath
org.testcontainers:postgresql:1.19.8=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.testcontainers:selenium:1.19.8=testCompileClasspath,testRuntimeClasspath
org.testcontainers:testcontainers:1.19.8=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.threeten:threetenbp:1.6.9=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.w3c.css:sac:1.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.webjars.npm:viz.js-graphviz-java:2.1.3=testRuntimeClasspath
org.xerial.snappy:snappy-java:1.1.10.4=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
@@ -46,7 +46,7 @@ import javax.net.ssl.HttpsURLConnection;
path = "/_dr/task/executeCannedScript",
method = {POST, GET},
automaticallyPrintOk = true,
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public class CannedScriptExecutionAction implements Runnable {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@@ -38,10 +38,7 @@ import org.joda.time.Days;
* An action that checks all {@link BulkPricingPackage} objects for compliance with their max create
* limit.
*/
@Action(
service = Service.BACKEND,
path = CheckBulkComplianceAction.PATH,
auth = Auth.AUTH_API_ADMIN)
@Action(service = Service.BACKEND, path = CheckBulkComplianceAction.PATH, auth = Auth.AUTH_ADMIN)
public class CheckBulkComplianceAction implements Runnable {
public static final String PATH = "/_dr/task/checkBulkCompliance";
@@ -187,18 +184,12 @@ public class CheckBulkComplianceAction implements Runnable {
.getLastNotificationSent()
.map(sentDate -> Days.daysBetween(sentDate, clock.nowUtc()).getDays())
.orElse(Integer.MAX_VALUE);
if (daysSinceLastNotification < THIRTY_DAYS) {
// Don't send an email if notification was already sent within the last 30
// days
continue;
} else if (daysSinceLastNotification < FORTY_DAYS) {
// Send an upgrade email if last email was between 30 and 40 days ago
// Send a warning email if 30-39 days since last notification and an upgrade email if 40+ days
if (daysSinceLastNotification >= THIRTY_DAYS) {
sendActiveDomainOverageEmail(
/* warning= */ false, bulkPricingPackage, overageList.get(bulkPricingPackage));
} else {
// Send a warning email
sendActiveDomainOverageEmail(
/* warning= */ true, bulkPricingPackage, overageList.get(bulkPricingPackage));
/* warning= */ daysSinceLastNotification >= FORTY_DAYS,
bulkPricingPackage,
overageList.get(bulkPricingPackage));
}
}
}
@@ -69,7 +69,7 @@ import org.joda.time.Duration;
@Action(
service = Action.Service.BACKEND,
path = DeleteExpiredDomainsAction.PATH,
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public class DeleteExpiredDomainsAction implements Runnable {
public static final String PATH = "/_dr/task/deleteExpiredDomains";
@@ -56,7 +56,7 @@ import javax.inject.Inject;
service = Action.Service.BACKEND,
path = "/_dr/task/deleteLoadTestData",
method = POST,
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public class DeleteLoadTestDataAction implements Runnable {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@@ -61,7 +61,7 @@ import org.joda.time.Duration;
service = Action.Service.BACKEND,
path = "/_dr/task/deleteProberData",
method = POST,
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public class DeleteProberDataAction implements Runnable {
// TODO(b/323026070): Add email alert on failure of this action
@@ -52,7 +52,7 @@ import org.joda.time.DateTime;
@Action(
service = Action.Service.BACKEND,
path = "/_dr/task/expandBillingRecurrences",
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public class ExpandBillingRecurrencesAction implements Runnable {
public static final String PARAM_START_TIME = "startTime";
@@ -53,7 +53,7 @@ import org.joda.time.Duration;
path = RelockDomainAction.PATH,
method = POST,
automaticallyPrintOk = true,
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public class RelockDomainAction implements Runnable {
public static final String PATH = "/_dr/task/relockDomain";
@@ -66,11 +66,15 @@ public class RelockDomainAction implements Runnable {
private static final Duration ONE_HOUR = Duration.standardHours(1);
private static final String RELOCK_SUCCESS_EMAIL_TEMPLATE =
"The domain %s was successfully re-locked.\n\nPlease contact support at %s if you have any "
+ "questions.";
"""
The domain %s was successfully re-locked.
Please contact support at %s if you have any questions.""";
private static final String RELOCK_NON_RETRYABLE_FAILURE_EMAIL_TEMPLATE =
"There was an error when automatically re-locking %s. Error message: %s\n\nPlease contact "
+ "support at %s if you have any questions.";
"""
There was an error when automatically re-locking %s. Error message: %s
Please contact support at %s if you have any questions.""";
private static final String RELOCK_TRANSIENT_FAILURE_EMAIL_TEMPLATE =
"There was an unexpected error when automatically re-locking %s. We will continue retrying "
+ "the lock for five hours. Please contact support at %s if you have any questions";
@@ -55,7 +55,7 @@ import javax.inject.Inject;
@Action(
service = Action.Service.BACKEND,
path = ResaveAllEppResourcesPipelineAction.PATH,
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public class ResaveAllEppResourcesPipelineAction implements Runnable {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@@ -40,7 +40,7 @@ import org.joda.time.DateTime;
@Action(
service = Action.Service.BACKEND,
path = ResaveEntityAction.PATH,
auth = Auth.AUTH_API_ADMIN,
auth = Auth.AUTH_ADMIN,
method = Method.POST)
public class ResaveEntityAction implements Runnable {
@@ -33,7 +33,7 @@ import google.registry.flows.certs.CertificateChecker;
import google.registry.groups.GmailClient;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.RegistrarPoc;
import google.registry.model.registrar.RegistrarPoc.Type;
import google.registry.model.registrar.RegistrarPocBase.Type;
import google.registry.request.Action;
import google.registry.request.Response;
import google.registry.request.auth.Auth;
@@ -51,7 +51,7 @@ import org.joda.time.format.DateTimeFormatter;
@Action(
service = Action.Service.BACKEND,
path = SendExpiringCertificateNotificationEmailAction.PATH,
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public class SendExpiringCertificateNotificationEmailAction implements Runnable {
public static final String PATH = "/_dr/task/sendExpiringCertificateNotificationEmail";
@@ -206,7 +206,7 @@ public class SendExpiringCertificateNotificationEmailAction implements Runnable
() -> {
Registrar.Builder newRegistrar = tm().loadByEntity(registrar).asBuilder();
switch (certificateType) {
case PRIMARY:
case PRIMARY -> {
newRegistrar.setLastExpiringCertNotificationSentDate(now);
tm().put(newRegistrar.build());
logger.atInfo().log(
@@ -215,8 +215,8 @@ public class SendExpiringCertificateNotificationEmailAction implements Runnable
DATE_FORMATTER.print(now),
certificateType.getDisplayName(),
registrar.getRegistrarName());
break;
case FAILOVER:
}
case FAILOVER -> {
newRegistrar.setLastExpiringFailoverCertNotificationSentDate(now);
tm().put(newRegistrar.build());
logger.atInfo().log(
@@ -225,13 +225,13 @@ public class SendExpiringCertificateNotificationEmailAction implements Runnable
DATE_FORMATTER.print(now),
certificateType.getDisplayName(),
registrar.getRegistrarName());
break;
default:
throw new IllegalArgumentException(
String.format(
"Unsupported certificate type: %s being passed in when updating "
+ "the last notification sent date to registrar %s.",
certificateType.toString(), registrar.getRegistrarName()));
}
default ->
throw new IllegalArgumentException(
String.format(
"Unsupported certificate type: %s being passed in when updating "
+ "the last notification sent date to registrar %s.",
certificateType.toString(), registrar.getRegistrarName()));
}
});
} catch (Exception e) {
@@ -51,7 +51,7 @@ import org.joda.time.DateTime;
@Action(
service = Service.BACKEND,
path = WipeOutContactHistoryPiiAction.PATH,
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public class WipeOutContactHistoryPiiAction implements Runnable {
public static final String PATH = "/_dr/task/wipeOutContactHistoryPii";
@@ -14,7 +14,6 @@
package google.registry.beam.billing;
import com.google.auto.value.AutoValue;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import google.registry.reporting.billing.BillingModule;
@@ -34,9 +33,39 @@ import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
/** A POJO representing a single billable event, parsed from a {@code SchemaAndRecord}. */
@AutoValue
public abstract class BillingEvent {
/**
* A record representing a single billable event, parsed from a {@code SchemaAndRecord}.
*
* @param id The unique ID for the {@code BillingEvent} associated with this event.
* @param billingTime The DateTime (in UTC) this event becomes billable.
* @param eventTime The DateTime (in UTC) this event was generated.
* @param registrarId The billed registrar's name.
* @param billingId The billed registrar's billing account key.
* @param poNumber The Purchase Order number.
* @param tld The TLD this event was generated for.
* @param action The billable action this event was generated for (CREATE, RENEW, TRANSFER...).
* @param domain The fully qualified domain name this event was generated for.
* @param repositoryId The unique RepoID associated with the billed domain.
* @param years The number of years this billing event is made out for.
* @param currency The 3-letter currency code for the billing event (USD or JPY).
* @param amount The total cost associated with this billing event.
* @param flags A list of space-delimited flags associated with the event.
*/
public record BillingEvent(
long id,
DateTime billingTime,
DateTime eventTime,
String registrarId,
String billingId,
String poNumber,
String tld,
String action,
String domain,
String repositoryId,
int years,
String currency,
double amount,
String flags) {
private static final DateTimeFormatter DATE_TIME_FORMATTER =
DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss zzz");
@@ -60,48 +89,6 @@ public abstract class BillingEvent {
"amount",
"flags");
/** Returns the unique ID for the {@code BillingEvent} associated with this event. */
abstract long id();
/** Returns the UTC DateTime this event becomes billable. */
abstract DateTime billingTime();
/** Returns the UTC DateTime this event was generated. */
abstract DateTime eventTime();
/** Returns the billed registrar's name. */
abstract String registrarId();
/** Returns the billed registrar's billing account key. */
abstract String billingId();
/** Returns the Purchase Order number. */
abstract String poNumber();
/** Returns the tld this event was generated for. */
abstract String tld();
/** Returns the billable action this event was generated for (i.e., RENEW, CREATE, TRANSFER...) */
abstract String action();
/** Returns the fully qualified domain name this event was generated for. */
abstract String domain();
/** Returns the unique RepoID associated with the billed domain. */
abstract String repositoryId();
/** Returns the number of years this billing event is made out for. */
abstract int years();
/** Returns the 3-letter currency code for the billing event (i.e., USD or JPY.) */
abstract String currency();
/** Returns the cost associated with this billing event. */
abstract double amount();
/** Returns a list of space-delimited flags associated with the event. */
abstract String flags();
/** Creates a concrete {@link BillingEvent}. */
static BillingEvent create(
long id,
@@ -118,7 +105,7 @@ public abstract class BillingEvent {
String currency,
double amount,
String flags) {
return new AutoValue_BillingEvent(
return new BillingEvent(
id,
billingTime,
eventTime,
@@ -338,7 +325,7 @@ public abstract class BillingEvent {
@Override
public BillingEvent decode(InputStream inStream) throws IOException {
return new AutoValue_BillingEvent(
return new BillingEvent(
longCoder.decode(inStream),
DATE_TIME_FORMATTER.parseDateTime(stringCoder.decode(inStream)),
DATE_TIME_FORMATTER.parseDateTime(stringCoder.decode(inStream)),
@@ -50,16 +50,17 @@ public class RegistryPipelineWorkerInitializer implements JvmInitializer {
environment.setup();
RegistryPipelineComponent registryPipelineComponent =
toRegistryPipelineComponent(registryOptions);
Lazy<JpaTransactionManager> transactionManagerLazy;
switch (registryOptions.getJpaTransactionManagerType()) {
case READ_ONLY_REPLICA:
transactionManagerLazy =
registryPipelineComponent.getReadOnlyReplicaJpaTransactionManager();
break;
case REGULAR:
default:
transactionManagerLazy = registryPipelineComponent.getJpaTransactionManager();
}
Lazy<JpaTransactionManager> transactionManagerLazy =
switch (registryOptions.getJpaTransactionManagerType()) {
case READ_ONLY_REPLICA ->
registryPipelineComponent.getReadOnlyReplicaJpaTransactionManager();
case REGULAR -> registryPipelineComponent.getJpaTransactionManager();
default ->
throw new IllegalStateException(
String.format(
"Unknown JPA transaction manager type: %s",
registryOptions.getJpaTransactionManagerType()));
};
TransactionManagerFactory.setJpaTmOnBeamWorker(transactionManagerLazy::get);
SystemPropertySetter.PRODUCTION_IMPL.setProperty(PROPERTY, "true");
}
@@ -58,7 +58,7 @@ import google.registry.model.host.Host;
import google.registry.model.host.HostHistory;
import google.registry.model.rde.RdeMode;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.Registrar.Type;
import google.registry.model.registrar.RegistrarBase.Type;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.reporting.HistoryEntry.HistoryEntryId;
import google.registry.persistence.PersistenceModule.TransactionIsolationLevel;
@@ -688,27 +688,26 @@ public class RdePipeline implements Serializable {
protected abstract static class TupleTags {
protected static final TupleTag<KV<PendingDeposit, DepositFragment>> DOMAIN_FRAGMENTS =
new TupleTag<KV<PendingDeposit, DepositFragment>>() {};
new TupleTag<>() {};
protected static final TupleTag<KV<String, PendingDeposit>> REFERENCED_CONTACTS =
new TupleTag<KV<String, PendingDeposit>>() {};
new TupleTag<>() {};
protected static final TupleTag<KV<String, PendingDeposit>> REFERENCED_HOSTS =
new TupleTag<KV<String, PendingDeposit>>() {};
new TupleTag<>() {};
protected static final TupleTag<KV<String, KV<String, CoGbkResult>>> SUPERORDINATE_DOMAINS =
new TupleTag<KV<String, KV<String, CoGbkResult>>>() {};
new TupleTag<>() {};
protected static final TupleTag<KV<PendingDeposit, DepositFragment>> EXTERNAL_HOST_FRAGMENTS =
new TupleTag<KV<PendingDeposit, DepositFragment>>() {};
new TupleTag<>() {};
protected static final TupleTag<PendingDeposit> PENDING_DEPOSIT =
new TupleTag<PendingDeposit>() {};
protected static final TupleTag<PendingDeposit> PENDING_DEPOSIT = new TupleTag<>() {};
protected static final TupleTag<KV<String, CoGbkResult>> HOST_TO_PENDING_DEPOSIT =
new TupleTag<KV<String, CoGbkResult>>() {};
new TupleTag<>() {};
protected static final TupleTag<Long> REVISION_ID = new TupleTag<Long>() {};
protected static final TupleTag<Long> REVISION_ID = new TupleTag<>() {};
}
@Singleton
@@ -14,30 +14,23 @@
package google.registry.beam.spec11;
import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
import java.io.Serializable;
/**
* A POJO representing a domain name and associated info, parsed from a {@code SchemaAndRecord}.
* A record representing a domain name and associated info, parsed from a {@code SchemaAndRecord}.
*
* <p>This is a trivially serializable class that allows Beam to transform the results of a SQL
* query into a standard Java representation.
*
* @param domainName The fully qualified domain name.
* @param domainRepoId The domain repo ID (the primary key of the domain table).
* @param registrarId The registrar ID of the associated registrar for this domain.
* @param registrarEmailAddress The email address of the registrar associated with this domain.
*/
@AutoValue
public abstract class DomainNameInfo implements Serializable {
/** Returns the fully qualified domain name. */
abstract String domainName();
/** Returns the domain repo ID (the primary key of the domain table). */
abstract String domainRepoId();
/** Returns the registrar ID of the associated registrar for this domain. */
abstract String registrarId();
/** Returns the email address of the registrar associated with this domain. */
abstract String registrarEmailAddress();
public record DomainNameInfo(
String domainName, String domainRepoId, String registrarId, String registrarEmailAddress)
implements Serializable {
/**
* Creates a concrete {@link DomainNameInfo}.
@@ -45,7 +38,6 @@ public abstract class DomainNameInfo implements Serializable {
@VisibleForTesting
static DomainNameInfo create(
String domainName, String domainRepoId, String registrarId, String registrarEmailAddress) {
return new AutoValue_DomainNameInfo(
domainName, domainRepoId, registrarId, registrarEmailAddress);
return new DomainNameInfo(domainName, domainRepoId, registrarId, registrarEmailAddress);
}
}
@@ -14,28 +14,26 @@
package google.registry.beam.spec11;
import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
import java.io.Serializable;
import org.json.JSONException;
import org.json.JSONObject;
/** A POJO representing a threat match response from the {@code SafeBrowsing API}. */
@AutoValue
public abstract class ThreatMatch implements Serializable {
/**
* A record representing a threat match response from the {@code SafeBrowsing API}.
*
* @param threatType What kind of threat this is (malware, phishing, etc.).
* @param domainName The fully qualified domain name of the matched threat.
*/
public record ThreatMatch(String threatType, String domainName) implements Serializable {
private static final String THREAT_TYPE_FIELD = "threatType";
private static final String DOMAIN_NAME_FIELD = "domainName";
private static final String OUTDATED_NAME_FIELD = "fullyQualifiedDomainName";
/** Returns what kind of threat it is (malware, phishing etc.) */
public abstract String threatType();
/** Returns the fully qualified domain name [SLD].[TLD] of the matched threat. */
public abstract String domainName();
@VisibleForTesting
static ThreatMatch create(String threatType, String domainName) {
return new AutoValue_ThreatMatch(threatType, domainName);
return new ThreatMatch(threatType, domainName);
}
/** Returns a {@link JSONObject} representing a subset of this object's data. */
@@ -49,7 +47,7 @@ public abstract class ThreatMatch implements Serializable {
public static ThreatMatch fromJSON(JSONObject threatMatch) throws JSONException {
// TODO: delete OUTDATED_NAME_FIELD once we no longer process reports saved with
// fullyQualifiedDomainName in them, likely 2023
return new AutoValue_ThreatMatch(
return new ThreatMatch(
threatMatch.getString(THREAT_TYPE_FIELD),
threatMatch.has(OUTDATED_NAME_FIELD)
? threatMatch.getString(OUTDATED_NAME_FIELD)
@@ -62,7 +62,7 @@ class BsaDiffCreator {
this.gcsClient = gcsClient;
}
private <K, V extends Comparable> Multimap<K, V> listBackedMultiMap() {
private <K, V extends Comparable<?>> Multimap<K, V> listBackedMultiMap() {
return newListMultimap(newHashMap(), Lists::newArrayList);
}
@@ -53,7 +53,7 @@ import javax.inject.Inject;
service = Action.Service.BSA,
path = BsaDownloadAction.PATH,
method = {GET, POST},
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public class BsaDownloadAction implements Runnable {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@@ -44,7 +44,7 @@ import org.joda.time.Duration;
service = Action.Service.BSA,
path = BsaRefreshAction.PATH,
method = {GET, POST},
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public class BsaRefreshAction implements Runnable {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@@ -70,7 +70,7 @@ import org.joda.time.Duration;
service = Action.Service.BSA,
path = BsaValidateAction.PATH,
method = {GET, POST},
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public class BsaValidateAction implements Runnable {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@@ -80,7 +80,7 @@ public class IdnChecker {
}
private static ImmutableMap<IdnTableEnum, ImmutableSet<Tld>> getIdnToTldMap(DateTime now) {
ImmutableMultimap.Builder<IdnTableEnum, Tld> idnToTldMap = new ImmutableMultimap.Builder();
var idnToTldMap = new ImmutableMultimap.Builder<IdnTableEnum, Tld>();
Tlds.getTldEntitiesOfType(TldType.REAL).stream()
.filter(tld -> isEnrolledWithBsa(tld, now))
.forEach(
@@ -23,9 +23,9 @@ import static google.registry.model.tld.label.ReservedList.loadReservedLists;
import static google.registry.persistence.transaction.TransactionManagerFactory.replicaTm;
import static google.registry.request.Action.Method.GET;
import static google.registry.request.Action.Method.POST;
import static jakarta.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
import static java.nio.charset.StandardCharsets.US_ASCII;
import com.google.api.client.http.HttpStatusCodes;
import com.google.cloud.storage.BlobId;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
@@ -75,7 +75,7 @@ import org.joda.time.DateTime;
service = Service.BSA,
path = "/_dr/task/uploadBsaUnavailableNames",
method = {GET, POST},
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public class UploadBsaUnavailableDomainsAction implements Runnable {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@@ -190,7 +190,7 @@ public class UploadBsaUnavailableDomainsAction implements Runnable {
return true;
} catch (IOException e) {
logger.atSevere().withCause(e).log("Error while attempting to upload to BSA, aborting.");
response.setStatus(HttpStatusCodes.STATUS_CODE_SERVER_ERROR);
response.setStatus(SC_INTERNAL_SERVER_ERROR);
response.setPayload("Error while attempting to upload to BSA: " + e.getMessage());
return false;
}
@@ -34,7 +34,7 @@ public record BlockOrder(long orderId, OrderType orderType) {
public static BlockOrder deserialize(String text) {
List<String> items = SPLITTER.splitToList(text);
try {
return create(Long.valueOf(items.get(0)), OrderType.valueOf(items.get(1)));
return create(Long.parseLong(items.get(0)), OrderType.valueOf(items.get(1)));
} catch (NumberFormatException ne) {
throw new IllegalArgumentException(text);
}
@@ -96,10 +96,9 @@ class BsaDomainRefresh {
if (this == o) {
return true;
}
if (!(o instanceof BsaDomainRefresh)) {
if (!(o instanceof BsaDomainRefresh that)) {
return false;
}
BsaDomainRefresh that = (BsaDomainRefresh) o;
return Objects.equal(jobId, that.jobId)
&& Objects.equal(creationTime, that.creationTime)
&& Objects.equal(updateTime, that.updateTime)
@@ -120,10 +120,9 @@ class BsaDownload {
if (this == o) {
return true;
}
if (!(o instanceof BsaDownload)) {
if (!(o instanceof BsaDownload that)) {
return false;
}
BsaDownload that = (BsaDownload) o;
return Objects.equal(creationTime, that.creationTime)
&& Objects.equal(updateTime, that.updateTime)
&& Objects.equal(blockListChecksums, that.blockListChecksums)
@@ -136,6 +135,6 @@ class BsaDownload {
}
static VKey<BsaDownload> vKey(long jobId) {
return VKey.create(BsaDownload.class, Long.valueOf(jobId));
return VKey.create(BsaDownload.class, jobId);
}
}
@@ -61,10 +61,9 @@ final class BsaLabel {
if (this == o) {
return true;
}
if (!(o instanceof BsaLabel)) {
if (!(o instanceof BsaLabel label1)) {
return false;
}
BsaLabel label1 = (BsaLabel) o;
return Objects.equal(label, label1.label) && Objects.equal(creationTime, label1.creationTime);
}
@@ -84,10 +84,9 @@ class BsaUnblockableDomain {
if (this == o) {
return true;
}
if (!(o instanceof BsaUnblockableDomain)) {
if (!(o instanceof BsaUnblockableDomain that)) {
return false;
}
BsaUnblockableDomain that = (BsaUnblockableDomain) o;
return Objects.equal(label, that.label)
&& Objects.equal(tld, that.tld)
&& reason == that.reason
@@ -142,10 +141,9 @@ class BsaUnblockableDomain {
if (this == o) {
return true;
}
if (!(o instanceof BsaUnblockableDomainId)) {
if (!(o instanceof BsaUnblockableDomainId that)) {
return false;
}
BsaUnblockableDomainId that = (BsaUnblockableDomainId) o;
return Objects.equal(label, that.label) && Objects.equal(tld, that.tld);
}
@@ -72,7 +72,7 @@ public final class LabelDiffUpdates {
for (Map.Entry<LabelType, ImmutableList<BlockLabel>> entry :
labelsByType.entrySet()) {
switch (entry.getKey()) {
case CREATE:
case CREATE -> {
// With current Cloud SQL, label upsert throughput is about 200/second. If
// better performance is needed, consider bulk insert in native SQL.
tm().putAll(
@@ -86,8 +86,8 @@ public final class LabelDiffUpdates {
// cached BsaLabels. Eventually will be consistent.
nonBlockedDomains.addAll(
tallyUnblockableDomainsForNewLabels(entry.getValue(), idnChecker, now));
break;
case DELETE:
}
case DELETE -> {
ImmutableSet<String> deletedLabels =
entry.getValue().stream()
.filter(label -> isValidInAtLeastOneTld(label, idnChecker))
@@ -100,8 +100,8 @@ public final class LabelDiffUpdates {
"Only found %s entities among the %s labels: [%s]",
nDeleted, deletedLabels.size(), deletedLabels);
}
break;
case NEW_ORDER_ASSOCIATION:
}
case NEW_ORDER_ASSOCIATION -> {
ImmutableSet<String> affectedLabels =
entry.getValue().stream()
.filter(label -> isValidInAtLeastOneTld(label, idnChecker))
@@ -120,13 +120,12 @@ public final class LabelDiffUpdates {
Queries.queryBsaUnblockableDomainByLabels(affectedLabels)
.map(BsaUnblockableDomain::toUnblockableDomain)
.forEach(nonBlockedDomains::add);
for (BlockLabel label : entry.getValue()) {
getInvalidTldsForLabel(label, idnChecker)
.map(tld -> UnblockableDomain.of(label.label(), tld, Reason.INVALID))
.forEach(nonBlockedDomains::add);
}
break;
}
}
}
});
@@ -103,7 +103,7 @@ public final class Queries {
static ImmutableList<BsaUnblockableDomain> batchReadUnblockables(
Optional<BsaUnblockableDomain> lastRead, int batchSize) {
return ImmutableList.copyOf(
return ImmutableList.<BsaUnblockableDomain>copyOf(
bsaQuery(
() ->
tm().getEntityManager()
@@ -203,6 +203,17 @@ public final class RegistryConfig {
return config.registrarConsole.announcementsEmailAddress;
}
/**
* The DUM file name, used as a file name base for DUM csv file
*
* @see google.registry.ui.server.console.ConsoleDumDownloadAction
*/
@Provides
@Config("dumFileName")
public static String provideDumFileName(RegistryConfigSettings config) {
return config.registrarConsole.dumFileName;
}
/**
* The contact phone number. Used in the "contact-us" section of the registrar console.
*
@@ -480,6 +491,18 @@ public final class RegistryConfig {
return Optional.ofNullable(Strings.emptyToNull(config.gSuite.supportGroupEmailAddress));
}
/**
* Returns the email address of the group containing emails of console users.
*
* <p>This group should be granted the {@code roles/iap.httpsResourceAccessor} role.
*/
@Provides
@Config("gSuiteConsoleUserGroupEmailAddress")
public static Optional<String> provideGSuiteConsoleUserGroupEmailAddress(
RegistryConfigSettings config) {
return Optional.ofNullable(Strings.emptyToNull(config.gSuite.consoleUserGroupEmailAddress));
}
/**
* Returns the email address(es) that notifications of registrar and/or registrar contact
* updates should be sent to, or the empty list if updates should not be sent.
@@ -83,6 +83,7 @@ public class RegistryConfigSettings {
public String outgoingEmailDisplayName;
public String adminAccountEmailAddress;
public String supportGroupEmailAddress;
public String consoleUserGroupEmailAddress;
}
/** Configuration options for registry policy. */
@@ -185,6 +186,7 @@ public class RegistryConfigSettings {
/** Configuration for the web-based registrar console. */
public static class RegistrarConsole {
public String dumFileName;
public String logoFilename;
public String supportPhoneNumber;
public String supportEmailAddress;
@@ -47,6 +47,11 @@ gSuite:
# given "ADMIN" role on the registrar console.
supportGroupEmailAddress: support@example.com
# Group containing the emails of console users. This group should be granted
# roles/iap.httpsResourceAccessor out-of-band. If this field is empty, each
# console user will be granted to the role individually when they are created.
consoleUserGroupEmailAddress:
registryPolicy:
# Repository identifier (ROID) suffix for contacts and hosts.
contactAndHostRoidSuffix: ROID
@@ -396,6 +401,9 @@ rde:
sshIdentityEmailAddress: rde@example.com
registrarConsole:
# DUM download file name, excluding the extension
dumFileName: dum_file_name
# Filename of the logo to use in the header of the console. This filename is
# relative to ui/assets/images/
logoFilename: logo.png
@@ -81,7 +81,7 @@ import javax.inject.Inject;
service = Action.Service.BACKEND,
path = "/_dr/cron/fanout",
automaticallyPrintOk = true,
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public final class TldFanoutAction implements Runnable {
/** A set of control params to TldFanoutAction that aren't passed down to the executing action. */
@@ -15,6 +15,7 @@
package google.registry.dns;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static google.registry.persistence.PersistenceModule.TransactionIsolationLevel.TRANSACTION_REPEATABLE_READ;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import com.google.common.collect.ImmutableCollection;
@@ -98,7 +99,9 @@ public final class DnsUtils {
*/
public static ImmutableList<DnsRefreshRequest> readAndUpdateRequestsWithLatestProcessTime(
String tld, Duration cooldown, int batchSize) {
// It is critical that below query use repeatable-read. See b/337894387.
return tm().transact(
TRANSACTION_REPEATABLE_READ,
() -> {
DateTime transactionTime = tm().getTransactionTime();
ImmutableList<DnsRefreshRequest> requests =
@@ -131,7 +134,9 @@ public final class DnsUtils {
* error because all we care about is that it no longer exists after the method runs.
*/
public static void deleteRequests(Collection<DnsRefreshRequest> requests) {
// It is critical that below query use repeatable-read. See b/337894387.
tm().transact(
TRANSACTION_REPEATABLE_READ,
() ->
tm().delete(
requests.stream()
@@ -38,7 +38,7 @@ public final class DnsWriterProxy {
/**
* Returns the instance of {@link DnsWriter} by class name.
*
* If the DnsWriter doesn't belong to this TLD, will return null.
* <p>If the DnsWriter doesn't belong to this TLD, will return null.
*/
public DnsWriter getByClassNameForTld(String className, String tld) {
if (!Tld.get(tld).getDnsWriters().contains(className)) {
@@ -50,6 +50,7 @@ import google.registry.model.domain.Domain;
import google.registry.model.host.Host;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.RegistrarPoc;
import google.registry.model.registrar.RegistrarPocBase;
import google.registry.model.tld.Tld;
import google.registry.request.Action;
import google.registry.request.Action.Service;
@@ -76,7 +77,7 @@ import org.joda.time.Duration;
path = PublishDnsUpdatesAction.PATH,
method = POST,
automaticallyPrintOk = true,
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public final class PublishDnsUpdatesAction implements Runnable, Callable<Void> {
public static final String PATH = "/_dr/task/publishDnsUpdates";
@@ -295,7 +296,7 @@ public final class PublishDnsUpdatesAction implements Runnable, Callable<Void> {
ImmutableList<InternetAddress> recipients =
registrar.get().getContacts().stream()
.filter(c -> c.getTypes().contains(RegistrarPoc.Type.ADMIN))
.filter(c -> c.getTypes().contains(RegistrarPocBase.Type.ADMIN))
.map(RegistrarPoc::getEmailAddress)
.map(PublishDnsUpdatesAction::emailToInternetAddress)
.collect(toImmutableList());
@@ -64,7 +64,7 @@ import org.joda.time.Duration;
path = "/_dr/task/readDnsRefreshRequests",
automaticallyPrintOk = true,
method = POST,
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public final class ReadDnsRefreshRequestsAction implements Runnable {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@@ -38,7 +38,7 @@ import javax.inject.Inject;
service = Action.Service.BACKEND,
path = "/_dr/dnsRefresh",
automaticallyPrintOk = true,
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public final class RefreshDnsAction implements Runnable {
private final Clock clock;
@@ -63,16 +63,15 @@ public final class RefreshDnsAction implements Runnable {
tm().transact(
() -> {
switch (type) {
case DOMAIN:
case DOMAIN -> {
loadAndVerifyExistence(Domain.class, domainOrHostName);
requestDomainDnsRefresh(domainOrHostName);
break;
case HOST:
}
case HOST -> {
verifyHostIsSubordinate(loadAndVerifyExistence(Host.class, domainOrHostName));
requestHostDnsRefresh(domainOrHostName);
break;
default:
throw new BadRequestException("Unsupported type: " + type);
}
default -> throw new BadRequestException("Unsupported type: " + type);
}
});
}
@@ -33,11 +33,7 @@ import google.registry.request.auth.Auth;
import javax.inject.Inject;
import org.joda.time.DateTime;
@Action(
service = Service.BACKEND,
path = PATH,
method = Action.Method.POST,
auth = Auth.AUTH_API_ADMIN)
@Action(service = Service.BACKEND, path = PATH, method = Action.Method.POST, auth = Auth.AUTH_ADMIN)
public class RefreshDnsOnHostRenameAction implements Runnable {
public static final String QUEUE_HOST_RENAME = "async-host-rename";
@@ -55,14 +55,14 @@ import org.xbill.DNS.Type;
import org.xbill.DNS.Update;
/**
* A DnsWriter that implements the DNS UPDATE protocol as specified in
* <a href="https://tools.ietf.org/html/rfc2136">RFC 2136</a>. Publishes changes in the
* domain-registry to a (capable) external DNS server, sometimes called a "hidden master". DNS
* UPDATE messages are sent via a supplied "transport" class.
* A DnsWriter that implements the DNS UPDATE protocol as specified in <a
* href="https://tools.ietf.org/html/rfc2136">RFC 2136</a>. Publishes changes in the domain-registry
* to a (capable) external DNS server, sometimes called a "hidden master". DNS UPDATE messages are
* sent via a supplied "transport" class.
*
* On call to {@link #commit()}, a single UPDATE message is created containing the records required
* to "synchronize" the DNS with the current (at the time of processing) state of the registry, for
* the supplied domain/host.
* <p>On call to {@link #commit()}, a single UPDATE message is created containing the records
* required to "synchronize" the DNS with the current (at the time of processing) state of the
* registry, for the supplied domain/host.
*
* <p>The general strategy of the publish methods is to delete <em>all</em> resource records of any
* <em>type</em> that match the exact domain/host name supplied. And then for create/update cases,
@@ -73,8 +73,8 @@ import org.xbill.DNS.Update;
* <p>Only NS, DS, A, and AAAA records are published, and in particular no DNSSEC signing is done
* assuming that this will be done by a third party DNS provider.
*
* <p>Each commit call is treated as an atomic update to the DNS. If a commit fails an exception
* is thrown. The SOA record serial number is implicitly incremented by the server on each UPDATE
* <p>Each commit call is treated as an atomic update to the DNS. If a commit fails an exception is
* thrown. The SOA record serial number is implicitly incremented by the server on each UPDATE
* message, as required by RFC 2136. Care must be taken to make sure the SOA serial number does not
* go backwards if the entire TLD (zone) is "reset" to empty and republished.
*/
@@ -17,4 +17,12 @@
<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>
@@ -12,6 +12,11 @@
<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>
@@ -49,7 +49,7 @@ import javax.inject.Inject;
service = Action.Service.BACKEND,
path = "/_dr/task/exportDomainLists",
method = POST,
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public class ExportDomainListsAction implements Runnable {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@@ -48,7 +48,7 @@ import javax.inject.Inject;
service = Action.Service.BACKEND,
path = "/_dr/task/exportPremiumTerms",
method = POST,
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public class ExportPremiumTermsAction implements Runnable {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@@ -37,7 +37,7 @@ import javax.inject.Inject;
service = Action.Service.BACKEND,
path = "/_dr/task/exportReservedTerms",
method = POST,
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public class ExportReservedTermsAction implements Runnable {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@@ -33,6 +33,7 @@ import google.registry.groups.GroupsConnection;
import google.registry.groups.GroupsConnection.Role;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.RegistrarPoc;
import google.registry.model.registrar.RegistrarPocBase;
import google.registry.request.Action;
import google.registry.request.Response;
import google.registry.request.auth.Auth;
@@ -55,7 +56,7 @@ import javax.inject.Inject;
service = Action.Service.BACKEND,
path = "/_dr/task/syncGroupMembers",
method = POST,
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public final class SyncGroupMembersAction implements Runnable {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@@ -99,7 +100,7 @@ public final class SyncGroupMembersAction implements Runnable {
* Returns the Google Groups email address for the given registrar ID and RegistrarContact.Type.
*/
public static String getGroupEmailAddressForContactType(
String registrarId, RegistrarPoc.Type type, String gSuiteDomainName) {
String registrarId, RegistrarPocBase.Type type, String gSuiteDomainName) {
// Take the registrar's ID, make it lowercase, and remove all characters that aren't
// alphanumeric, hyphens, or underscores.
return String.format(
@@ -174,7 +175,7 @@ public final class SyncGroupMembersAction implements Runnable {
Set<RegistrarPoc> registrarPocs = registrar.getContacts();
long totalAdded = 0;
long totalRemoved = 0;
for (final RegistrarPoc.Type type : RegistrarPoc.Type.values()) {
for (final RegistrarPocBase.Type type : RegistrarPocBase.Type.values()) {
groupKey =
getGroupEmailAddressForContactType(registrar.getRegistrarId(), type, gSuiteDomainName);
Set<String> currentMembers = groupsConnection.getMembersOfGroup(groupKey);
@@ -17,13 +17,13 @@ package google.registry.export.sheet;
import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static google.registry.model.common.Cursor.CursorType.SYNC_REGISTRAR_SHEET;
import static google.registry.model.registrar.RegistrarPoc.Type.ABUSE;
import static google.registry.model.registrar.RegistrarPoc.Type.ADMIN;
import static google.registry.model.registrar.RegistrarPoc.Type.BILLING;
import static google.registry.model.registrar.RegistrarPoc.Type.LEGAL;
import static google.registry.model.registrar.RegistrarPoc.Type.MARKETING;
import static google.registry.model.registrar.RegistrarPoc.Type.TECH;
import static google.registry.model.registrar.RegistrarPoc.Type.WHOIS;
import static google.registry.model.registrar.RegistrarPocBase.Type.ABUSE;
import static google.registry.model.registrar.RegistrarPocBase.Type.ADMIN;
import static google.registry.model.registrar.RegistrarPocBase.Type.BILLING;
import static google.registry.model.registrar.RegistrarPocBase.Type.LEGAL;
import static google.registry.model.registrar.RegistrarPocBase.Type.MARKETING;
import static google.registry.model.registrar.RegistrarPocBase.Type.TECH;
import static google.registry.model.registrar.RegistrarPocBase.Type.WHOIS;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
@@ -36,6 +36,7 @@ import google.registry.model.common.Cursor;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.RegistrarAddress;
import google.registry.model.registrar.RegistrarPoc;
import google.registry.model.registrar.RegistrarPocBase;
import google.registry.util.Clock;
import google.registry.util.DateTimeUtils;
import java.io.IOException;
@@ -173,7 +174,7 @@ class SyncRegistrarsSheet {
return result.toString();
}
private static Predicate<RegistrarPoc> byType(final RegistrarPoc.Type type) {
private static Predicate<RegistrarPoc> byType(final RegistrarPocBase.Type type) {
return contact -> contact.getTypes().contains(type);
}
@@ -57,7 +57,7 @@ import org.joda.time.Duration;
service = Action.Service.BACKEND,
path = SyncRegistrarsSheetAction.PATH,
method = POST,
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public class SyncRegistrarsSheetAction implements Runnable {
private enum Result {
@@ -29,7 +29,7 @@ import javax.inject.Inject;
service = Action.Service.DEFAULT,
path = "/_dr/epp",
method = Method.POST,
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public class EppTlsAction implements Runnable {
@Inject @Payload byte[] inputXmlBytes;
@@ -33,7 +33,7 @@ import javax.inject.Inject;
service = Action.Service.TOOLS,
path = EppToolAction.PATH,
method = Method.POST,
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public class EppToolAction implements Runnable {
public static final String PATH = "/_dr/epptool";
@@ -22,9 +22,9 @@ public interface TransportCredentials {
/**
* Check that these credentials are valid for the registrar and optionally check the password.
*
* Called by {@link google.registry.flows.session.LoginFlow LoginFlow} to check the transport
* credentials against the stored registrar's credentials. If they do not match, throw an
* {@link AuthenticationErrorException}.
* <p>Called by {@link google.registry.flows.session.LoginFlow LoginFlow} to check the transport
* credentials against the stored registrar's credentials. If they do not match, throw an {@link
* AuthenticationErrorException}.
*/
void validate(Registrar registrar, String password) throws AuthenticationErrorException;
@@ -16,12 +16,10 @@ package google.registry.flows.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Predicates.equalTo;
import static com.google.common.base.Strings.emptyToNull;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableMap.toImmutableMap;
import static com.google.common.collect.ImmutableSetMultimap.toImmutableSetMultimap;
import static com.google.common.collect.Iterables.any;
import static com.google.common.collect.Sets.difference;
import static com.google.common.collect.Sets.intersection;
import static com.google.common.collect.Sets.union;
@@ -95,6 +93,7 @@ import google.registry.model.domain.DomainCommand.Update;
import google.registry.model.domain.DomainHistory;
import google.registry.model.domain.ForeignKeyedDesignatedContact;
import google.registry.model.domain.Period;
import google.registry.model.domain.Period.Unit;
import google.registry.model.domain.fee.BaseFee;
import google.registry.model.domain.fee.BaseFee.FeeType;
import google.registry.model.domain.fee.Credit;
@@ -121,9 +120,9 @@ import google.registry.model.domain.token.AllocationToken.RegistrationBehavior;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.eppoutput.EppResponse.ResponseExtension;
import google.registry.model.host.Host;
import google.registry.model.poll.PollMessage;
import google.registry.model.poll.PollMessage.Autorenew;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.Registrar.State;
import google.registry.model.registrar.RegistrarBase.State;
import google.registry.model.reporting.DomainTransactionRecord;
import google.registry.model.reporting.DomainTransactionRecord.TransactionReportField;
import google.registry.model.reporting.HistoryEntry.HistoryEntryId;
@@ -206,7 +205,7 @@ public class DomainFlowUtils {
if (parts.size() <= 1) {
throw new BadDomainNamePartsCountException();
}
if (any(parts, equalTo(""))) {
if (parts.stream().anyMatch(String::isEmpty)) {
throw new EmptyDomainNamePartException();
}
validateFirstLabel(parts.get(0));
@@ -329,7 +328,7 @@ public class DomainFlowUtils {
/** Check if the registrar running the flow has access to the TLD in question. */
public static void checkAllowedAccessToTld(String registrarId, String tld) throws EppException {
if (!Registrar.loadByRegistrarIdCached(registrarId).get().getAllowedTlds().contains(tld)) {
throw new DomainFlowUtils.NotAuthorizedForTldException(tld);
throw new NotAuthorizedForTldException(tld);
}
}
@@ -344,7 +343,7 @@ public class DomainFlowUtils {
.get()
.getBillingAccountMap()
.containsKey(tld.getCurrency())) {
throw new DomainFlowUtils.MissingBillingAccountMapException(tld.getCurrency());
throw new MissingBillingAccountMapException(tld.getCurrency());
}
}
@@ -405,7 +404,7 @@ public class DomainFlowUtils {
/** We only allow specifying years in a period. */
static Period verifyUnitIsYears(Period period) throws EppException {
if (!checkNotNull(period).getUnit().equals(Period.Unit.YEARS)) {
if (!checkNotNull(period).getUnit().equals(Unit.YEARS)) {
throw new BadPeriodUnitException();
}
return period;
@@ -534,7 +533,7 @@ public class DomainFlowUtils {
public static boolean isReserved(InternetDomainName domainName, boolean isSunrise) {
ImmutableSet<ReservationType> types = getReservationTypes(domainName);
return !Sets.intersection(types, RESERVED_TYPES).isEmpty()
return !intersection(types, RESERVED_TYPES).isEmpty()
|| !(isSunrise || intersection(TYPES_ALLOWED_FOR_CREATE_ONLY_IN_SUNRISE, types).isEmpty());
}
@@ -601,8 +600,8 @@ public class DomainFlowUtils {
* Fills in a builder with the data needed for an autorenew poll message for this domain. This
* does not copy over the id of the current autorenew poll message.
*/
public static PollMessage.Autorenew.Builder newAutorenewPollMessage(Domain domain) {
return new PollMessage.Autorenew.Builder()
public static Autorenew.Builder newAutorenewPollMessage(Domain domain) {
return new Autorenew.Builder()
.setTargetId(domain.getDomainName())
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
.setEventTime(domain.getRegistrationExpirationTime())
@@ -623,7 +622,7 @@ public class DomainFlowUtils {
BillingRecurrence existingBillingRecurrence,
DateTime newEndTime,
@Nullable HistoryEntryId historyId) {
Optional<PollMessage.Autorenew> autorenewPollMessage =
Optional<Autorenew> autorenewPollMessage =
tm().loadByKeyIfPresent(domain.getAutorenewPollMessage());
// Construct an updated autorenew poll message. If the autorenew poll message no longer exists,
@@ -632,7 +631,7 @@ public class DomainFlowUtils {
// message to be deleted), and then subsequently the transfer was canceled, rejected, or deleted
// (which would cause the poll message to be recreated here). In the latter case, the history id
// of the event that created the new poll message will also be used.
PollMessage.Autorenew updatedAutorenewPollMessage;
Autorenew updatedAutorenewPollMessage;
if (autorenewPollMessage.isPresent()) {
updatedAutorenewPollMessage =
autorenewPollMessage.get().asBuilder().setAutorenewEndTime(newEndTime).build();
@@ -706,7 +705,7 @@ public class DomainFlowUtils {
String feeClass = null;
ImmutableList<Fee> fees = ImmutableList.of();
switch (feeRequest.getCommandName()) {
case CREATE:
case CREATE -> {
// Don't return a create price for reserved names.
if (isReserved(domainName, isSunrise) && !isAvailable) {
feeClass = "reserved";
@@ -726,16 +725,16 @@ public class DomainFlowUtils {
allocationToken)
.getFees();
}
break;
case RENEW:
}
case RENEW -> {
builder.setAvailIfSupported(true);
fees =
pricingLogic
.getRenewPrice(
tld, domainNameString, now, years, billingRecurrence, allocationToken)
.getFees();
break;
case RESTORE:
}
case RESTORE -> {
// The minimum allowable period per the EPP spec is 1, so, strangely, 1 year still has to be
// passed in as the period for a restore even if the domain would *not* be renewed as part
// of a restore. This is fixed in RFC 8748 (which is a more recent version of the fee
@@ -751,21 +750,20 @@ public class DomainFlowUtils {
boolean isExpired =
domain.isPresent() && domain.get().getRegistrationExpirationTime().isBefore(now);
fees = pricingLogic.getRestorePrice(tld, domainNameString, now, isExpired).getFees();
break;
case TRANSFER:
}
case TRANSFER -> {
if (years != 1) {
throw new TransfersAreAlwaysForOneYearException();
}
builder.setAvailIfSupported(true);
fees =
pricingLogic.getTransferPrice(tld, domainNameString, now, billingRecurrence).getFees();
break;
case UPDATE:
}
case UPDATE -> {
builder.setAvailIfSupported(true);
fees = pricingLogic.getUpdatePrice(tld, domainNameString, now).getFees();
break;
default:
throw new UnknownFeeCommandException(feeRequest.getUnparsedCommandName());
}
default -> throw new UnknownFeeCommandException(feeRequest.getUnparsedCommandName());
}
if (feeClass == null) {
@@ -138,14 +138,14 @@ public final class DomainPricingLogic {
isRenewCostPremiumPrice = domainPrices.isPremium();
} else {
switch (billingRecurrence.getRenewalPriceBehavior()) {
case DEFAULT:
case DEFAULT -> {
renewCost =
getDomainRenewCostWithDiscount(tld, domainPrices, dateTime, years, allocationToken);
isRenewCostPremiumPrice = domainPrices.isPremium();
break;
}
// if the renewal price behavior is specified, then the renewal price should be the same
// as the creation price, which is stored in the billing event as the renewal price
case SPECIFIED:
case SPECIFIED -> {
checkArgumentPresent(
billingRecurrence.getRenewalPrice(),
"Unexpected behavior: renewal price cannot be null when renewal behavior is"
@@ -153,20 +153,24 @@ public final class DomainPricingLogic {
// Don't apply allocation token to renewal price when SPECIFIED
renewCost = billingRecurrence.getRenewalPrice().get().multipliedBy(years);
isRenewCostPremiumPrice = false;
break;
}
// if the renewal price behavior is nonpremium, it means that the domain should be renewed
// at standard price of domains at the time, even if the domain is premium
case NONPREMIUM:
case NONPREMIUM -> {
renewCost =
getDomainCostWithDiscount(
false, years, allocationToken, tld.getStandardRenewCost(dateTime));
false,
years,
allocationToken,
tld.getStandardRenewCost(dateTime),
Optional.empty());
isRenewCostPremiumPrice = false;
break;
default:
throw new IllegalArgumentException(
String.format(
"Unknown RenewalPriceBehavior enum value: %s",
billingRecurrence.getRenewalPriceBehavior()));
}
default ->
throw new IllegalArgumentException(
String.format(
"Unknown RenewalPriceBehavior enum value: %s",
billingRecurrence.getRenewalPriceBehavior()));
}
}
return customLogic.customizeRenewPrice(
@@ -252,7 +256,11 @@ public final class DomainPricingLogic {
DomainPrices domainPrices, int years, Optional<AllocationToken> allocationToken)
throws EppException {
return getDomainCostWithDiscount(
domainPrices.isPremium(), years, allocationToken, domainPrices.getCreateCost());
domainPrices.isPremium(),
years,
allocationToken,
domainPrices.getCreateCost(),
Optional.of(domainPrices.getRenewCost()));
}
/** Returns the domain renew cost with allocation-token-related discounts applied. */
@@ -272,24 +280,45 @@ public final class DomainPricingLogic {
}
}
return getDomainCostWithDiscount(
domainPrices.isPremium(), years, allocationToken, domainPrices.getRenewCost());
domainPrices.isPremium(),
years,
allocationToken,
domainPrices.getRenewCost(),
Optional.empty());
}
/**
* Returns the domain creation or renewal cost for the given number of {@code years}.
*
* <p>For domain creation, {@code firstYearCost} is the creation cost while {@code
* subsequentYearCost} is the single-year renewal cost (which is guaranteed to be present).
*
* <p>For domain renewal, {@code firstYearCost} is the single-year renewal cost and {@code
* subsequentYearCost} should be empty.
*/
private Money getDomainCostWithDiscount(
boolean isPremium, int years, Optional<AllocationToken> allocationToken, Money oneYearCost)
boolean isPremium,
int years,
Optional<AllocationToken> allocationToken,
Money firstYearCost,
Optional<Money> subsequentYearCost)
throws AllocationTokenInvalidForPremiumNameException {
checkArgument(years > 0, "Registration years to get cost for must be positive.");
validateTokenForPossiblePremiumName(allocationToken, isPremium);
Money totalDomainFlowCost = oneYearCost.multipliedBy(years);
Money totalDomainFlowCost =
firstYearCost.plus(subsequentYearCost.orElse(firstYearCost).multipliedBy(years - 1));
// Apply the allocation token discount, if applicable.
if (allocationToken.isPresent()
&& allocationToken.get().getTokenBehavior().equals(TokenBehavior.DEFAULT)) {
int discountedYears = Math.min(years, allocationToken.get().getDiscountYears());
Money discount =
oneYearCost.multipliedBy(
discountedYears * allocationToken.get().getDiscountFraction(),
RoundingMode.HALF_EVEN);
totalDomainFlowCost = totalDomainFlowCost.minus(discount);
if (discountedYears > 0) {
var discount =
firstYearCost
.plus(subsequentYearCost.orElse(firstYearCost).multipliedBy(discountedYears - 1))
.multipliedBy(allocationToken.get().getDiscountFraction(), RoundingMode.HALF_EVEN);
totalDomainFlowCost = totalDomainFlowCost.minus(discount);
}
}
return totalDomainFlowCost;
}
@@ -124,22 +124,21 @@ public class FlowPicker {
}};
/** Poll flows have an {@link InnerCommand} of type {@link Poll}. */
private static final FlowProvider POLL_FLOW_PROVIDER = new FlowProvider() {
@Override
Class<? extends Flow> get(
EppInput eppInput, InnerCommand innerCommand, ResourceCommand resourceCommand) {
if (!(innerCommand instanceof Poll)) {
return null;
}
switch (((Poll) innerCommand).getPollOp()) {
case ACK:
return PollAckFlow.class;
case REQUEST:
return PollRequestFlow.class;
default:
return UnimplementedFlow.class;
}
}};
private static final FlowProvider POLL_FLOW_PROVIDER =
new FlowProvider() {
@Override
Class<? extends Flow> get(
EppInput eppInput, InnerCommand innerCommand, ResourceCommand resourceCommand) {
if (!(innerCommand instanceof Poll)) {
return null;
}
return switch (((Poll) innerCommand).getPollOp()) {
case ACK -> PollAckFlow.class;
case REQUEST -> PollRequestFlow.class;
default -> UnimplementedFlow.class;
};
}
};
/**
* The domain restore command is technically a domain {@literal <update>}, but logically a totally
@@ -54,8 +54,7 @@ public final class PollFlowUtils {
if (pollMessage instanceof PollMessage.OneTime) {
// One-time poll messages are deleted once acked.
tm().delete(pollMessage.createVKey());
} else if (pollMessage instanceof PollMessage.Autorenew) {
PollMessage.Autorenew autorenewPollMessage = (PollMessage.Autorenew) pollMessage;
} else if (pollMessage instanceof PollMessage.Autorenew autorenewPollMessage) {
// Move the eventTime of this autorenew poll message forward by a year.
DateTime nextEventTime = autorenewPollMessage.getEventTime().plusYears(1);
@@ -130,23 +130,22 @@ public final class PgpHelper {
while (keys.hasNext()) {
PGPPublicKey key = keys.next();
switch (want) {
case ENCRYPT:
case ENCRYPT -> {
if (key.isEncryptionKey()) {
return Optional.of(key);
}
break;
case SIGN:
}
case SIGN -> {
if (isSigningKey(key)) {
return Optional.of(key);
}
break;
case ENCRYPT_SIGN:
}
case ENCRYPT_SIGN -> {
if (key.isEncryptionKey() && isSigningKey(key)) {
return Optional.of(key);
}
break;
default:
throw new AssertionError();
}
default -> throw new AssertionError();
}
}
return Optional.empty();
@@ -154,14 +153,9 @@ public final class PgpHelper {
/** Returns {@code true} if this key can be used for signing. */
public static boolean isSigningKey(PGPPublicKey key) {
switch (key.getAlgorithm()) {
case RSA_GENERAL:
case RSA_SIGN:
case DSA:
case ELGAMAL_GENERAL:
return true;
default:
return false;
}
return switch (key.getAlgorithm()) {
case RSA_GENERAL, RSA_SIGN, DSA, ELGAMAL_GENERAL -> true;
default -> false;
};
}
}
@@ -58,7 +58,7 @@ import org.joda.time.DateTime;
path = LoadTestAction.PATH,
method = Action.Method.POST,
automaticallyPrintOk = true,
auth = Auth.AUTH_API_ADMIN)
auth = Auth.AUTH_ADMIN)
public class LoadTestAction implements Runnable {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@@ -350,9 +350,8 @@ public class LoadTestAction implements Runnable {
.toBuilder()
.getAppEngineHttpRequest()
.toBuilder()
// instead of adding the X_CSRF_TOKEN to params, this remains as part of
// headers because of the existing setup for authentication in {@link
// google.registry.request.auth.LegacyAuthenticationMechanism}
// TODO: investigate if the following is necessary now that
// LegacyAuthenticationMechanism is gone.
.putHeaders(X_CSRF_TOKEN, xsrfToken)
.build())
.setScheduleTime(
@@ -109,16 +109,18 @@ public class ModelUtils {
if (value != null && value.getClass().isArray()) {
// It's surprisingly difficult to convert arrays into lists if the array might be primitive.
final Object arrayValue = value;
value = new AbstractList<Object>() {
@Override
public Object get(int index) {
return Array.get(arrayValue, index);
}
value =
new AbstractList<>() {
@Override
public Object get(int index) {
return Array.get(arrayValue, index);
}
@Override
public int size() {
return Array.getLength(arrayValue);
}};
@Override
public int size() {
return Array.getLength(arrayValue);
}
};
}
values.put(field, value);
}
@@ -0,0 +1,99 @@
// Copyright 2024 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.model.console;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.reporting.HistoryEntry.HistoryEntryId;
import google.registry.persistence.VKey;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.AttributeOverride;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Index;
import javax.persistence.Table;
/**
* A persisted history object representing an EPP action via the console.
*
* <p>In addition to the generic history fields (time, URL, etc.) we also persist a reference to the
* history entry so that we can refer to it if necessary.
*/
@Access(AccessType.FIELD)
@Entity
@Table(
indexes = {
@Index(columnList = "historyActingUser"),
@Index(columnList = "repoId"),
@Index(columnList = "revisionId")
})
public class ConsoleEppActionHistory extends ConsoleUpdateHistory {
@AttributeOverride(name = "repoId", column = @Column(nullable = false))
HistoryEntryId historyEntryId;
@Column(nullable = false)
Class<? extends HistoryEntry> historyEntryClass;
public HistoryEntryId getHistoryEntryId() {
return historyEntryId;
}
public Class<? extends HistoryEntry> getHistoryEntryClass() {
return historyEntryClass;
}
/** Creates a {@link VKey} instance for this entity. */
@Override
public VKey<ConsoleEppActionHistory> createVKey() {
return VKey.create(ConsoleEppActionHistory.class, getRevisionId());
}
@Override
public Builder asBuilder() {
return new Builder(clone(this));
}
/** Builder for the immutable UserUpdateHistory. */
public static class Builder
extends ConsoleUpdateHistory.Builder<ConsoleEppActionHistory, Builder> {
public Builder() {}
public Builder(ConsoleEppActionHistory instance) {
super(instance);
}
@Override
public ConsoleEppActionHistory build() {
checkArgumentNotNull(getInstance().historyEntryId, "History entry ID must be specified");
checkArgumentNotNull(
getInstance().historyEntryClass, "History entry class must be specified");
return super.build();
}
public Builder setHistoryEntryId(HistoryEntryId historyEntryId) {
getInstance().historyEntryId = historyEntryId;
return this;
}
public Builder setHistoryEntryClass(Class<? extends HistoryEntry> historyEntryClass) {
getInstance().historyEntryClass = historyEntryClass;
return this;
}
}
}
@@ -0,0 +1,168 @@
// Copyright 2024 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.model.console;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import google.registry.model.Buildable;
import google.registry.model.ImmutableObject;
import google.registry.model.annotations.IdAllocation;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import org.joda.time.DateTime;
/**
* A record of a resource that was updated through the console.
*
* <p>This abstract class has several subclasses that (mostly) include the modified resource itself
* so that the entire object history is persisted to SQL.
*/
@Access(AccessType.FIELD)
@MappedSuperclass
public abstract class ConsoleUpdateHistory extends ImmutableObject implements Buildable {
public enum Type {
EPP_ACTION,
POC_CREATE,
POC_UPDATE,
POC_DELETE,
REGISTRAR_UPDATE,
USER_CREATE,
USER_DELETE,
USER_UPDATE
}
/** Autogenerated ID of this event. */
@Id
@IdAllocation
@Column(nullable = false, name = "historyRevisionId")
protected Long revisionId;
/** The user that performed the modification. */
@JoinColumn(name = "historyActingUser", referencedColumnName = "emailAddress", nullable = false)
@ManyToOne
User actingUser;
/** The URL of the action that was used to make the modification. */
@Column(nullable = false, name = "historyUrl")
String url;
/** The HTTP method (e.g. POST, PUT) used to make this modification. */
@Column(nullable = false, name = "historyMethod")
String method;
/** The raw body of the request that was used to make this modification. */
@Column(name = "historyRequestBody")
String requestBody;
/** The time at which the modification was mode. */
@Column(nullable = false, name = "historyModificationTime")
DateTime modificationTime;
/** The type of modification. */
@Column(nullable = false, name = "historyType")
@Enumerated(EnumType.STRING)
Type type;
public long getRevisionId() {
return revisionId;
}
public User getActingUser() {
return actingUser;
}
public String getUrl() {
return url;
}
public String getMethod() {
return method;
}
public String getRequestBody() {
return requestBody;
}
public DateTime getModificationTime() {
return modificationTime;
}
public Type getType() {
return type;
}
@Override
public abstract Builder<? extends ConsoleUpdateHistory, ?> asBuilder();
/** Builder for the immutable ConsoleUpdateHistory. */
public abstract static class Builder<
T extends ConsoleUpdateHistory, B extends ConsoleUpdateHistory.Builder<?, ?>>
extends GenericBuilder<T, B> {
protected Builder() {}
protected Builder(T instance) {
super(instance);
}
@Override
public T build() {
checkArgumentNotNull(getInstance().actingUser, "Acting user must be specified");
checkArgumentNotNull(getInstance().url, "URL must be specified");
checkArgumentNotNull(getInstance().method, "HTTP method must be specified");
checkArgumentNotNull(getInstance().modificationTime, "modificationTime must be specified");
checkArgumentNotNull(getInstance().type, "Console History type must be specified");
return super.build();
}
public B setActingUser(User actingUser) {
getInstance().actingUser = actingUser;
return thisCastToDerived();
}
public B setUrl(String url) {
getInstance().url = url;
return thisCastToDerived();
}
public B setMethod(String method) {
getInstance().method = method;
return thisCastToDerived();
}
public B setRequestBody(String requestBody) {
getInstance().requestBody = requestBody;
return thisCastToDerived();
}
public B setModificationTime(DateTime modificationTime) {
getInstance().modificationTime = modificationTime;
return thisCastToDerived();
}
public B setType(Type type) {
getInstance().type = type;
return thisCastToDerived();
}
}
}
@@ -0,0 +1,99 @@
// Copyright 2024 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.model.console;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import google.registry.model.registrar.RegistrarPoc;
import google.registry.model.registrar.RegistrarPocBase;
import google.registry.persistence.VKey;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Index;
import javax.persistence.PostLoad;
import javax.persistence.Table;
/**
* A persisted history object representing an update to a RegistrarPoc.
*
* <p>In addition to the generic history fields (time, URL, etc.) we also persist a copy of the
* modified RegistrarPoc object at this point in time.
*/
@Access(AccessType.FIELD)
@Entity
@Table(
indexes = {
@Index(columnList = "historyActingUser"),
@Index(columnList = "emailAddress"),
@Index(columnList = "registrarId")
})
public class RegistrarPocUpdateHistory extends ConsoleUpdateHistory {
RegistrarPocBase registrarPoc;
// These fields exist so that they can be populated in the SQL table
@Column(nullable = false)
String emailAddress;
@Column(nullable = false)
String registrarId;
public RegistrarPocBase getRegistrarPoc() {
return registrarPoc;
}
@PostLoad
void postLoad() {
registrarPoc.setEmailAddress(emailAddress);
registrarPoc.setRegistrarId(registrarId);
}
/** Creates a {@link VKey} instance for this entity. */
@Override
public VKey<RegistrarPocUpdateHistory> createVKey() {
return VKey.create(RegistrarPocUpdateHistory.class, getRevisionId());
}
@Override
public Builder asBuilder() {
return new Builder(clone(this));
}
/** Builder for the immutable UserUpdateHistory. */
public static class Builder
extends ConsoleUpdateHistory.Builder<RegistrarPocUpdateHistory, Builder> {
public Builder() {}
public Builder(RegistrarPocUpdateHistory instance) {
super(instance);
}
@Override
public RegistrarPocUpdateHistory build() {
checkArgumentNotNull(getInstance().registrarPoc, "Registrar POC must be specified");
return super.build();
}
public Builder setRegistrarPoc(RegistrarPoc registrarPoc) {
getInstance().registrarPoc = registrarPoc;
getInstance().registrarId = registrarPoc.getRegistrarId();
getInstance().emailAddress = registrarPoc.getEmailAddress();
return this;
}
}
}
@@ -0,0 +1,89 @@
// Copyright 2024 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.model.console;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import google.registry.model.registrar.RegistrarBase;
import google.registry.persistence.VKey;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Index;
import javax.persistence.PostLoad;
import javax.persistence.Table;
/**
* A persisted history object representing an update to a Registrar.
*
* <p>In addition to the generic history fields (time, URL, etc.) we also persist a copy of the
* modified Registrar object at this point in time.
*/
@Access(AccessType.FIELD)
@Entity
@Table(indexes = {@Index(columnList = "historyActingUser"), @Index(columnList = "registrarId")})
public class RegistrarUpdateHistory extends ConsoleUpdateHistory {
RegistrarBase registrar;
// This field exists so that it exists in the SQL table
@Column(nullable = false)
@SuppressWarnings("unused")
private String registrarId;
public RegistrarBase getRegistrar() {
return registrar;
}
@PostLoad
void postLoad() {
registrar.setRegistrarId(registrarId);
}
/** Creates a {@link VKey} instance for this entity. */
@Override
public VKey<RegistrarUpdateHistory> createVKey() {
return VKey.create(RegistrarUpdateHistory.class, getRevisionId());
}
@Override
public Builder asBuilder() {
return new RegistrarUpdateHistory.Builder(clone(this));
}
/** Builder for the immutable UserUpdateHistory. */
public static class Builder
extends ConsoleUpdateHistory.Builder<RegistrarUpdateHistory, Builder> {
public Builder() {}
public Builder(RegistrarUpdateHistory instance) {
super(instance);
}
@Override
public RegistrarUpdateHistory build() {
checkArgumentNotNull(getInstance().registrar, "Registrar must be specified");
return super.build();
}
public Builder setRegistrar(RegistrarBase registrar) {
getInstance().registrar = registrar;
getInstance().registrarId = registrar.getRegistrarId();
return this;
}
}
}
@@ -14,19 +14,10 @@
package google.registry.model.console;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.isNullOrEmpty;
import static com.google.common.io.BaseEncoding.base64;
import static google.registry.model.registrar.Registrar.checkValidEmail;
import static google.registry.util.PasswordUtils.SALT_SUPPLIER;
import static google.registry.util.PasswordUtils.hashPassword;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import google.registry.model.Buildable;
import google.registry.model.UpdateAutoTimestampEntity;
import google.registry.persistence.VKey;
import google.registry.util.PasswordUtils;
import javax.persistence.Column;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
@@ -35,74 +26,17 @@ import javax.persistence.Index;
import javax.persistence.Table;
/** A console user, either a registry employee or a registrar partner. */
@Embeddable
@Entity
@Table(indexes = {@Index(columnList = "emailAddress", name = "user_email_address_idx")})
public class User extends UpdateAutoTimestampEntity implements Buildable {
public class User extends UserBase {
private static final long serialVersionUID = 6936728603828566721L;
/** Autogenerated unique ID of this user. */
@Override
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/** Email address of the user in question. */
@Column(nullable = false)
private String emailAddress;
/** Roles (which grant permissions) associated with this user. */
@Column(nullable = false)
private UserRoles userRoles;
/**
* A hashed password that exists iff this contact is registry-lock-enabled. The hash is a base64
* encoded SHA256 string.
*/
String registryLockPasswordHash;
/** Randomly generated hash salt. */
String registryLockPasswordSalt;
@Access(AccessType.PROPERTY)
public Long getId() {
return id;
}
public String getEmailAddress() {
return emailAddress;
}
public UserRoles getUserRoles() {
return userRoles;
}
public boolean hasRegistryLockPassword() {
return !isNullOrEmpty(registryLockPasswordHash) && !isNullOrEmpty(registryLockPasswordSalt);
}
public boolean verifyRegistryLockPassword(String registryLockPassword) {
if (isNullOrEmpty(registryLockPassword)
|| isNullOrEmpty(registryLockPasswordSalt)
|| isNullOrEmpty(registryLockPasswordHash)) {
return false;
}
return PasswordUtils.verifyPassword(
registryLockPassword, registryLockPasswordHash, registryLockPasswordSalt);
}
/**
* Whether the user has the registry lock permission on any registrar or globally.
*
* <p>If so, they should be allowed to (re)set their registry lock password.
*/
public boolean hasAnyRegistryLockPermission() {
if (userRoles == null) {
return false;
}
if (userRoles.isAdmin() || userRoles.hasGlobalPermission(ConsolePermission.REGISTRY_LOCK)) {
return true;
}
return userRoles.getRegistrarRoles().values().stream()
.anyMatch(role -> role.hasPermission(ConsolePermission.REGISTRY_LOCK));
return super.getId();
}
@Override
@@ -116,49 +50,12 @@ public class User extends UpdateAutoTimestampEntity implements Buildable {
}
/** Builder for constructing immutable {@link User} objects. */
public static class Builder extends Buildable.Builder<User> {
public static class Builder extends UserBase.Builder<User, Builder> {
public Builder() {}
public Builder(User user) {
super(user);
}
@Override
public User build() {
checkArgumentNotNull(getInstance().emailAddress, "Email address cannot be null");
checkArgumentNotNull(getInstance().userRoles, "User roles cannot be null");
return super.build();
}
public Builder setEmailAddress(String emailAddress) {
getInstance().emailAddress = checkValidEmail(emailAddress);
return this;
}
public Builder setUserRoles(UserRoles userRoles) {
checkArgumentNotNull(userRoles, "User roles cannot be null");
getInstance().userRoles = userRoles;
return this;
}
public Builder removeRegistryLockPassword() {
getInstance().registryLockPasswordHash = null;
getInstance().registryLockPasswordSalt = null;
return this;
}
public Builder setRegistryLockPassword(String registryLockPassword) {
checkArgument(
getInstance().hasAnyRegistryLockPermission(), "User has no registry lock permission");
checkArgument(
!getInstance().hasRegistryLockPassword(), "User already has a password, remove it first");
checkArgument(
!isNullOrEmpty(registryLockPassword), "Registry lock password was null or empty");
byte[] salt = SALT_SUPPLIER.get();
getInstance().registryLockPasswordSalt = base64().encode(salt);
getInstance().registryLockPasswordHash = hashPassword(registryLockPassword, salt);
return this;
}
}
}
@@ -0,0 +1,193 @@
// Copyright 2024 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.model.console;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.isNullOrEmpty;
import static com.google.common.io.BaseEncoding.base64;
import static google.registry.model.registrar.Registrar.checkValidEmail;
import static google.registry.util.PasswordUtils.SALT_SUPPLIER;
import static google.registry.util.PasswordUtils.hashPassword;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import google.registry.model.Buildable;
import google.registry.model.UpdateAutoTimestampEntity;
import google.registry.util.PasswordUtils;
import java.util.Optional;
import javax.annotation.Nullable;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
/**
* A console user, either a registry employee or a registrar partner.
*
* <p>This class deliberately does not include an {@link Id} so that any foreign-keyed fields can
* refer to the proper parent entity's ID, whether we're storing this in the DB itself or as part of
* another entity.
*/
@Access(AccessType.FIELD)
@Embeddable
@MappedSuperclass
public class UserBase extends UpdateAutoTimestampEntity implements Buildable {
private static final long serialVersionUID = 6936728603828566721L;
/** Autogenerated unique ID of this user. */
@Transient private Long id;
/** Email address of the user in question. */
@Column(nullable = false)
String emailAddress;
/** Optional external email address to use for registry lock confirmation emails. */
@Column String registryLockEmailAddress;
/** Roles (which grant permissions) associated with this user. */
@Column(nullable = false)
UserRoles userRoles;
/**
* A hashed password that exists iff this contact is registry-lock-enabled. The hash is a base64
* encoded SHA256 string.
*/
String registryLockPasswordHash;
/** Randomly generated hash salt. */
String registryLockPasswordSalt;
public Long getId() {
return id;
}
/**
* Sets the user ID.
*
* <p>This should only be used for restoring the user id of an object being loaded in a PostLoad
* method (effectively, when it is still under construction by Hibernate). In all other cases, the
* object should be regarded as immutable and changes should go through a Builder.
*
* <p>In addition to this special case use, this method must exist to satisfy Hibernate.
*/
@SuppressWarnings("unused")
void setId(Long id) {
this.id = id;
}
public String getEmailAddress() {
return emailAddress;
}
public Optional<String> getRegistryLockEmailAddress() {
return Optional.ofNullable(registryLockEmailAddress);
}
public UserRoles getUserRoles() {
return userRoles;
}
public boolean hasRegistryLockPassword() {
return !isNullOrEmpty(registryLockPasswordHash) && !isNullOrEmpty(registryLockPasswordSalt);
}
public boolean verifyRegistryLockPassword(String registryLockPassword) {
if (isNullOrEmpty(registryLockPassword)
|| isNullOrEmpty(registryLockPasswordSalt)
|| isNullOrEmpty(registryLockPasswordHash)) {
return false;
}
return PasswordUtils.verifyPassword(
registryLockPassword, registryLockPasswordHash, registryLockPasswordSalt);
}
/**
* Whether the user has the registry lock permission on any registrar or globally.
*
* <p>If so, they should be allowed to (re)set their registry lock password.
*/
public boolean hasAnyRegistryLockPermission() {
if (userRoles == null) {
return false;
}
if (userRoles.isAdmin() || userRoles.hasGlobalPermission(ConsolePermission.REGISTRY_LOCK)) {
return true;
}
return userRoles.getRegistrarRoles().values().stream()
.anyMatch(role -> role.hasPermission(ConsolePermission.REGISTRY_LOCK));
}
@Override
public Builder<? extends UserBase, ?> asBuilder() {
return new Builder<>(clone(this));
}
/** Builder for constructing immutable {@link UserBase} objects. */
public static class Builder<T extends UserBase, B extends Builder<T, B>>
extends GenericBuilder<T, B> {
public Builder() {}
public Builder(T abstractUser) {
super(abstractUser);
}
@Override
public T build() {
checkArgumentNotNull(getInstance().emailAddress, "Email address cannot be null");
checkArgumentNotNull(getInstance().userRoles, "User roles cannot be null");
return super.build();
}
public B setEmailAddress(String emailAddress) {
getInstance().emailAddress = checkValidEmail(emailAddress);
return thisCastToDerived();
}
public B setRegistryLockEmailAddress(@Nullable String registryLockEmailAddress) {
getInstance().registryLockEmailAddress =
registryLockEmailAddress == null ? null : checkValidEmail(registryLockEmailAddress);
return thisCastToDerived();
}
public B setUserRoles(UserRoles userRoles) {
checkArgumentNotNull(userRoles, "User roles cannot be null");
getInstance().userRoles = userRoles;
return thisCastToDerived();
}
public B removeRegistryLockPassword() {
getInstance().registryLockPasswordHash = null;
getInstance().registryLockPasswordSalt = null;
return thisCastToDerived();
}
public B setRegistryLockPassword(String registryLockPassword) {
checkArgument(
getInstance().hasAnyRegistryLockPermission(), "User has no registry lock permission");
checkArgument(
!getInstance().hasRegistryLockPassword(), "User already has a password, remove it first");
checkArgument(
!isNullOrEmpty(registryLockPassword), "Registry lock password was null or empty");
byte[] salt = SALT_SUPPLIER.get();
getInstance().registryLockPasswordSalt = base64().encode(salt);
getInstance().registryLockPasswordHash = hashPassword(registryLockPassword, salt);
return thisCastToDerived();
}
}
}
@@ -21,6 +21,8 @@ import com.google.common.collect.ImmutableMap;
import google.registry.model.Buildable;
import google.registry.model.ImmutableObject;
import java.util.Map;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.EnumType;
@@ -32,6 +34,7 @@ import javax.persistence.Enumerated;
* <p>See <a href="https://go/nomulus-console-authz">go/nomulus-console-authz</a> for more
* information.
*/
@Access(AccessType.FIELD)
@Embeddable
public class UserRoles extends ImmutableObject implements Buildable {
@@ -0,0 +1,86 @@
// Copyright 2024 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.model.console;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import google.registry.persistence.VKey;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Index;
import javax.persistence.PostLoad;
import javax.persistence.Table;
/**
* A persisted history object representing an update to a User.
*
* <p>In addition to the generic history fields (time, URL, etc.) we also persist a copy of the
* modified User object at this point in time.
*/
@Access(AccessType.FIELD)
@Entity
@Table(indexes = {@Index(columnList = "historyActingUser"), @Index(columnList = "emailAddress")})
public class UserUpdateHistory extends ConsoleUpdateHistory {
UserBase user;
// This field exists so that it's populated in the SQL table
@Column(nullable = false, name = "userId")
Long id;
public UserBase getUser() {
return user;
}
@PostLoad
void postLoad() {
user.setId(id);
}
/** Creates a {@link VKey} instance for this entity. */
@Override
public VKey<UserUpdateHistory> createVKey() {
return VKey.create(UserUpdateHistory.class, getRevisionId());
}
@Override
public Builder asBuilder() {
return new Builder(clone(this));
}
/** Builder for the immutable UserUpdateHistory. */
public static class Builder extends ConsoleUpdateHistory.Builder<UserUpdateHistory, Builder> {
public Builder() {}
public Builder(UserUpdateHistory instance) {
super(instance);
}
@Override
public UserUpdateHistory build() {
checkArgumentNotNull(getInstance().user, "User must be specified");
return super.build();
}
public Builder setUser(User user) {
getInstance().user = user;
getInstance().id = user.getId();
return this;
}
}
}
@@ -61,7 +61,8 @@ import org.joda.time.DateTime;
@Index(columnList = "lordnPhase"),
@Index(columnList = "billing_recurrence_id"),
@Index(columnList = "transfer_billing_event_id"),
@Index(columnList = "transfer_billing_recurrence_id")
@Index(columnList = "transfer_billing_recurrence_id"),
@Index(columnList = "transfer_billing_cancellation_id")
})
@WithVKey(String.class)
@ExternalMessagingName("domain")
@@ -659,22 +659,17 @@ public class DomainBase extends EppResource
contact.getType());
contactsDiscovered.add(contact.getType());
switch (contact.getType()) {
case BILLING:
billingContact = contact.getContactKey();
break;
case TECH:
techContact = contact.getContactKey();
break;
case ADMIN:
adminContact = contact.getContactKey();
break;
case REGISTRANT:
case BILLING -> billingContact = contact.getContactKey();
case TECH -> techContact = contact.getContactKey();
case ADMIN -> adminContact = contact.getContactKey();
case REGISTRANT -> {
if (includeRegistrant) {
registrantContact = contact.getContactKey();
}
break;
default:
throw new IllegalArgumentException("Unknown contact resource type: " + contact.getType());
}
default ->
throw new IllegalArgumentException(
"Unknown contact resource type: " + contact.getType());
}
}
}
@@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.util.DateTimeUtils.isBeforeOrAt;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import com.google.gson.annotations.Expose;
import google.registry.model.Buildable;
import google.registry.model.CreateAutoTimestamp;
import google.registry.model.UpdateAutoTimestampEntity;
@@ -90,6 +91,7 @@ public final class RegistryLock extends UpdateAutoTimestampEntity implements Bui
// TODO (b/140568328): remove this when everything is in Cloud SQL and we can join on "domain"
@Column(nullable = false)
@Expose
private String domainName;
/**
@@ -100,7 +102,7 @@ public final class RegistryLock extends UpdateAutoTimestampEntity implements Bui
private String registrarId;
/** The POC that performed the action, or null if it was a superuser. */
private String registrarPocId;
@Expose private String registrarPocId;
/** When the lock is first requested. */
@AttributeOverrides({
@@ -108,22 +110,23 @@ public final class RegistryLock extends UpdateAutoTimestampEntity implements Bui
name = "creationTime",
column = @Column(name = "lockRequestTime", nullable = false))
})
@Expose
private final CreateAutoTimestamp lockRequestTime = CreateAutoTimestamp.create(null);
/** When the unlock is first requested. */
private DateTime unlockRequestTime;
@Expose private DateTime unlockRequestTime;
/**
* When the user has verified the lock. If this field is null, it means the lock has not been
* verified yet (and thus not been put into effect).
*/
private DateTime lockCompletionTime;
@Expose private DateTime lockCompletionTime;
/**
* When the user has verified the unlock of this lock. If this field is null, it means the unlock
* action has not been verified yet (and has not been put into effect).
*/
private DateTime unlockCompletionTime;
@Expose private DateTime unlockCompletionTime;
/** The user must provide the random verification code in order to complete the action. */
@Column(nullable = false)
@@ -134,6 +137,7 @@ public final class RegistryLock extends UpdateAutoTimestampEntity implements Bui
* this case, the action was performed by a registry admin rather than a registrar.
*/
@Column(nullable = false)
@Expose
private boolean isSuperuser;
/** The lock that undoes this lock, if this lock has been unlocked and the domain locked again. */

Some files were not shown because too many files have changed in this diff Show More