mirror of
https://github.com/google/nomulus
synced 2026-01-16 10:43:06 +00:00
Compare commits
32 Commits
test
...
nomulus-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee5a2d3916 | ||
|
|
2b5643df4c | ||
|
|
6bbd7a2290 | ||
|
|
77ab80f3dc | ||
|
|
5e1cd0120f | ||
|
|
0167dad85f | ||
|
|
1eaf3d4aa8 | ||
|
|
d9c46170dd | ||
|
|
e8a475f48b | ||
|
|
bdaab9daa5 | ||
|
|
7e07fabf7e | ||
|
|
16859bb36a | ||
|
|
7c92928f2c | ||
|
|
de8d205657 | ||
|
|
4738b979e4 | ||
|
|
a61a667992 | ||
|
|
1164070576 | ||
|
|
d23640a54f | ||
|
|
cc347264f1 | ||
|
|
e5d4cbb9fc | ||
|
|
8c1e0ff4de | ||
|
|
5cef2dd8b5 | ||
|
|
62b2585220 | ||
|
|
8692fe35db | ||
|
|
18614ba11e | ||
|
|
427f6db820 | ||
|
|
5aa40b2208 | ||
|
|
95c89bc856 | ||
|
|
c21b66f0fb | ||
|
|
b070c46231 | ||
|
|
a20eb8d1e9 | ||
|
|
338b8edb97 |
@@ -3,7 +3,7 @@
|
||||
# This file is expected to be part of source control.
|
||||
aopalliance:aopalliance:1.0=annotationProcessor,errorprone,testAnnotationProcessor,testingAnnotationProcessor
|
||||
com.github.ben-manes.caffeine:caffeine:3.0.5=annotationProcessor,errorprone,testAnnotationProcessor,testingAnnotationProcessor
|
||||
com.github.ben-manes.caffeine:caffeine:3.2.0=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath,testing,testingCompileClasspath
|
||||
com.github.ben-manes.caffeine:caffeine:3.2.2=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath,testing,testingCompileClasspath
|
||||
com.github.kevinstern:software-and-algorithms:1.0=annotationProcessor,errorprone,testAnnotationProcessor,testingAnnotationProcessor
|
||||
com.google.auto.service:auto-service-annotations:1.0.1=annotationProcessor,errorprone,testAnnotationProcessor,testingAnnotationProcessor
|
||||
com.google.auto.value:auto-value-annotations:1.11.0=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath,testing,testingCompileClasspath
|
||||
@@ -12,13 +12,13 @@ com.google.auto:auto-common:1.2.1=annotationProcessor,errorprone,testAnnotationP
|
||||
com.google.code.findbugs:jsr305:3.0.2=annotationProcessor,checkstyle,compileClasspath,deploy_jar,errorprone,runtimeClasspath,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath,testing,testingAnnotationProcessor,testingCompileClasspath
|
||||
com.google.errorprone:error_prone_annotation:2.23.0=annotationProcessor,errorprone,testAnnotationProcessor,testingAnnotationProcessor
|
||||
com.google.errorprone:error_prone_annotations:2.23.0=annotationProcessor,errorprone,testAnnotationProcessor,testingAnnotationProcessor
|
||||
com.google.errorprone:error_prone_annotations:2.36.0=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath,testing,testingCompileClasspath
|
||||
com.google.errorprone:error_prone_annotations:2.40.0=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath,testing,testingCompileClasspath
|
||||
com.google.errorprone:error_prone_annotations:2.7.1=checkstyle
|
||||
com.google.errorprone:error_prone_check_api:2.23.0=annotationProcessor,errorprone,testAnnotationProcessor,testingAnnotationProcessor
|
||||
com.google.errorprone:error_prone_core:2.23.0=annotationProcessor,errorprone,testAnnotationProcessor,testingAnnotationProcessor
|
||||
com.google.errorprone:error_prone_type_annotations:2.23.0=annotationProcessor,errorprone,testAnnotationProcessor,testingAnnotationProcessor
|
||||
com.google.errorprone:javac:9+181-r4173-1=errorproneJavac
|
||||
com.google.flogger:flogger:0.8=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath,testing,testingCompileClasspath
|
||||
com.google.flogger:flogger:0.9=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath,testing,testingCompileClasspath
|
||||
com.google.guava:failureaccess:1.0.1=annotationProcessor,checkstyle,errorprone,testAnnotationProcessor,testingAnnotationProcessor
|
||||
com.google.guava:failureaccess:1.0.2=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath,testing,testingCompileClasspath
|
||||
com.google.guava:guava-parent:32.1.1-jre=annotationProcessor,errorprone,testAnnotationProcessor,testingAnnotationProcessor
|
||||
@@ -37,15 +37,14 @@ commons-collections:commons-collections:3.2.2=checkstyle
|
||||
info.picocli:picocli:4.6.2=checkstyle
|
||||
io.github.eisop:dataflow-errorprone:3.34.0-eisop1=annotationProcessor,errorprone,testAnnotationProcessor,testingAnnotationProcessor
|
||||
io.github.java-diff-utils:java-diff-utils:4.12=annotationProcessor,errorprone,testAnnotationProcessor,testingAnnotationProcessor
|
||||
io.github.java-diff-utils:java-diff-utils:4.15=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath,testing,testingCompileClasspath
|
||||
io.github.java-diff-utils:java-diff-utils:4.16=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath,testing,testingCompileClasspath
|
||||
jakarta.inject:jakarta.inject-api:2.0.1=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath,testing,testingCompileClasspath
|
||||
javax.inject:javax.inject:1=annotationProcessor,errorprone,testAnnotationProcessor,testingAnnotationProcessor
|
||||
joda-time:joda-time:2.13.1=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath,testing,testingCompileClasspath
|
||||
joda-time:joda-time:2.14.0=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath,testing,testingCompileClasspath
|
||||
junit:junit:4.13.2=testCompileClasspath,testRuntimeClasspath,testing,testingCompileClasspath
|
||||
net.sf.saxon:Saxon-HE:10.6=checkstyle
|
||||
org.antlr:antlr4-runtime:4.9.3=checkstyle
|
||||
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath
|
||||
org.checkerframework:checker-compat-qual:2.5.3=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath,testing,testingCompileClasspath
|
||||
org.checkerframework:checker-qual:3.12.0=checkstyle
|
||||
org.checkerframework:checker-qual:3.33.0=annotationProcessor,errorprone,testAnnotationProcessor,testingAnnotationProcessor
|
||||
org.checkerframework:checker-qual:3.42.0=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath,testing,testingCompileClasspath
|
||||
@@ -56,12 +55,12 @@ org.jacoco:org.jacoco.core:0.8.12=jacocoAnt
|
||||
org.jacoco:org.jacoco.report:0.8.12=jacocoAnt
|
||||
org.javassist:javassist:3.28.0-GA=checkstyle
|
||||
org.jspecify:jspecify:1.0.0=compileClasspath,deploy_jar,runtimeClasspath,testCompileClasspath,testRuntimeClasspath,testing,testingCompileClasspath
|
||||
org.junit.jupiter:junit-jupiter-api:5.12.1=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-engine:5.12.1=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-commons:1.12.1=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-engine:1.12.1=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-launcher:1.12.1=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit:junit-bom:5.12.1=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-api:5.13.4=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-engine:5.13.4=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-commons:1.13.4=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-engine:1.13.4=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-launcher:1.13.4=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit:junit-bom:5.13.4=testCompileClasspath,testRuntimeClasspath
|
||||
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.ow2.asm:asm-commons:9.7=jacocoAnt
|
||||
org.ow2.asm:asm-tree:9.7=jacocoAnt
|
||||
|
||||
@@ -92,17 +92,19 @@ public class TextDiffSubject extends Subject {
|
||||
|
||||
private ImmutableList<String> filterComments(List<String> lines) {
|
||||
return lines.stream()
|
||||
.filter(line -> !line.isBlank())
|
||||
.filter(line -> comments.stream().noneMatch(line::startsWith))
|
||||
.collect(ImmutableList.toImmutableList());
|
||||
}
|
||||
|
||||
public void hasSameContentAs(List<String> expectedContent) {
|
||||
checkNotNull(expectedContent, "expectedContent");
|
||||
ImmutableList<String> expected = filterComments(expectedContent);
|
||||
if (filterComments(expected).equals(filterComments(actual))) {
|
||||
ImmutableList<String> filteredExpected = filterComments(expectedContent);
|
||||
ImmutableList<String> filteredActual = filterComments(actual);
|
||||
if (filteredExpected.equals(filteredActual)) {
|
||||
return;
|
||||
}
|
||||
String diffString = diffFormat.generateDiff(expected, actual);
|
||||
String diffString = diffFormat.generateDiff(filteredExpected, filteredActual);
|
||||
failWithoutActual(
|
||||
Fact.simpleFact(
|
||||
Joiner.on('\n')
|
||||
|
||||
@@ -26,6 +26,7 @@ import SecurityComponent from './settings/security/security.component';
|
||||
import { SettingsComponent } from './settings/settings.component';
|
||||
import { SupportComponent } from './support/support.component';
|
||||
import RdapComponent from './settings/rdap/rdap.component';
|
||||
import { PasswordResetVerifyComponent } from './shared/components/passwordReset/passwordResetVerify.component';
|
||||
|
||||
export interface RouteWithIcon extends Route {
|
||||
iconName?: string;
|
||||
@@ -38,6 +39,10 @@ export const PATHS = {
|
||||
};
|
||||
export const routes: RouteWithIcon[] = [
|
||||
{ path: '', redirectTo: '/home', pathMatch: 'full' },
|
||||
{
|
||||
path: PasswordResetVerifyComponent.PATH,
|
||||
component: PasswordResetVerifyComponent,
|
||||
},
|
||||
{
|
||||
path: RegistryLockVerifyComponent.PATH,
|
||||
component: RegistryLockVerifyComponent,
|
||||
|
||||
@@ -61,6 +61,8 @@ import { ForceFocusDirective } from './shared/directives/forceFocus.directive';
|
||||
import RdapComponent from './settings/rdap/rdap.component';
|
||||
import RdapEditComponent from './settings/rdap/rdapEdit.component';
|
||||
import { PocReminderComponent } from './shared/components/pocReminder/pocReminder.component';
|
||||
import { PasswordResetVerifyComponent } from './shared/components/passwordReset/passwordResetVerify.component';
|
||||
import { PasswordInputForm } from './shared/components/passwordReset/passwordInputForm.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [SelectedRegistrarWrapper],
|
||||
@@ -84,10 +86,12 @@ export class SelectedRegistrarModule {}
|
||||
NavigationComponent,
|
||||
NewRegistrarComponent,
|
||||
NotificationsComponent,
|
||||
PasswordInputForm,
|
||||
PasswordResetVerifyComponent,
|
||||
PocReminderComponent,
|
||||
RdapComponent,
|
||||
RdapEditComponent,
|
||||
ReasonDialogComponent,
|
||||
PocReminderComponent,
|
||||
RegistrarComponent,
|
||||
RegistrarDetailsComponent,
|
||||
RegistrarSelectorComponent,
|
||||
|
||||
@@ -25,7 +25,10 @@ export class RegistrarSelectorComponent {
|
||||
registrarInput = signal<string>(this.registrarService.registrarId());
|
||||
filteredOptions?: string[];
|
||||
allRegistrarIds = computed(() =>
|
||||
this.registrarService.registrars().map((r) => r.registrarId)
|
||||
this.registrarService
|
||||
.registrars()
|
||||
.map((r) => r.registrarId)
|
||||
.sort()
|
||||
);
|
||||
|
||||
constructor(protected registrarService: RegistrarService) {
|
||||
|
||||
@@ -16,65 +16,22 @@
|
||||
<p class="secondary-text">
|
||||
Passwords must be between 6 and 16 alphanumeric characters
|
||||
</p>
|
||||
<form
|
||||
(ngSubmit)="save()"
|
||||
<password-input-form-component
|
||||
[displayOldPasswordField]="true"
|
||||
[formGroup]="passwordUpdateForm"
|
||||
class="settings-security__edit-password-form"
|
||||
>
|
||||
<div class="settings-security__edit-password-field">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Old password: </mat-label>
|
||||
<input
|
||||
matInput
|
||||
type="text"
|
||||
formControlName="oldPassword"
|
||||
required
|
||||
autocomplete="current-password"
|
||||
/>
|
||||
<mat-error *ngIf="hasError('oldPassword') as errorText">{{
|
||||
errorText
|
||||
}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="settings-security__edit-password-field">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>New password: </mat-label>
|
||||
<input
|
||||
matInput
|
||||
type="text"
|
||||
formControlName="newPassword"
|
||||
required
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
<mat-error *ngIf="hasError('newPassword') as errorText">{{
|
||||
errorText
|
||||
}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="settings-security__edit-password-field">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Confirm new password: </mat-label>
|
||||
<input
|
||||
matInput
|
||||
type="text"
|
||||
formControlName="newPasswordRepeat"
|
||||
required
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
<mat-error *ngIf="hasError('newPasswordRepeat') as errorText">{{
|
||||
errorText
|
||||
}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
(submitResults)="save($event)"
|
||||
/>
|
||||
@if(userDataService.userData()?.isAdmin) {
|
||||
<div class="settings-security__reset-password-field">
|
||||
<h2>Need to reset your EPP password?</h2>
|
||||
<button
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
[disabled]="!passwordUpdateForm.valid"
|
||||
aria-label="Save epp password update"
|
||||
type="submit"
|
||||
class="settings-security__edit-password-save"
|
||||
aria-label="Reset EPP password via email"
|
||||
(click)="requestEppPasswordReset()"
|
||||
>
|
||||
Save
|
||||
Reset EPP password via email
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
.settings-security__edit-password {
|
||||
max-width: 616px;
|
||||
&-field {
|
||||
width: 100%;
|
||||
mat-form-field {
|
||||
margin-bottom: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
&-form {
|
||||
margin-top: 30px;
|
||||
}
|
||||
&-save {
|
||||
margin-top: 30px;
|
||||
// Copyright 2025 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.
|
||||
|
||||
.settings-security {
|
||||
&__reset-password-field {
|
||||
margin-top: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,20 +14,46 @@
|
||||
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { Component } from '@angular/core';
|
||||
import {
|
||||
AbstractControl,
|
||||
FormControl,
|
||||
FormGroup,
|
||||
ValidatorFn,
|
||||
Validators,
|
||||
} from '@angular/forms';
|
||||
import { FormControl, FormGroup, Validators } from '@angular/forms';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { RegistrarService } from 'src/app/registrar/registrar.service';
|
||||
import { SecurityService } from './security.service';
|
||||
import { UserDataService } from 'src/app/shared/services/userData.service';
|
||||
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MaterialModule } from 'src/app/material.module';
|
||||
import { filter, switchMap, take } from 'rxjs';
|
||||
import { BackendService } from 'src/app/shared/services/backend.service';
|
||||
import {
|
||||
PasswordInputForm,
|
||||
PasswordResults,
|
||||
} from 'src/app/shared/components/passwordReset/passwordInputForm.component';
|
||||
|
||||
type errorCode = 'required' | 'maxlength' | 'minlength' | 'passwordsDontMatch';
|
||||
@Component({
|
||||
selector: 'app-reset-epp-password-dialog',
|
||||
template: `
|
||||
<h2 mat-dialog-title>Please confirm the password reset:</h2>
|
||||
<mat-dialog-content>
|
||||
This will send an EPP password reset email to the admin POC.
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions>
|
||||
<button mat-button (click)="onCancel()">Cancel</button>
|
||||
<button mat-button color="warn" (click)="onSave()">Confirm</button>
|
||||
</mat-dialog-actions>
|
||||
`,
|
||||
imports: [CommonModule, MaterialModule],
|
||||
})
|
||||
export class ResetEppPasswordComponent {
|
||||
constructor(public dialogRef: MatDialogRef<ResetEppPasswordComponent>) {}
|
||||
|
||||
type errorFriendlyText = { [type in errorCode]: String };
|
||||
onSave(): void {
|
||||
this.dialogRef.close(true);
|
||||
}
|
||||
|
||||
onCancel(): void {
|
||||
this.dialogRef.close(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-epp-password-edit',
|
||||
@@ -36,76 +62,38 @@ type errorFriendlyText = { [type in errorCode]: String };
|
||||
standalone: false,
|
||||
})
|
||||
export default class EppPasswordEditComponent {
|
||||
MIN_MAX_LENGHT = new String(
|
||||
'Passwords must be between 6 and 16 alphanumeric characters'
|
||||
);
|
||||
|
||||
errorTextMap: errorFriendlyText = {
|
||||
required: "This field can't be empty",
|
||||
maxlength: this.MIN_MAX_LENGHT,
|
||||
minlength: this.MIN_MAX_LENGHT,
|
||||
passwordsDontMatch: "Passwords don't match",
|
||||
};
|
||||
|
||||
constructor(
|
||||
public securityService: SecurityService,
|
||||
private _snackBar: MatSnackBar,
|
||||
public registrarService: RegistrarService
|
||||
) {}
|
||||
|
||||
hasError(controlName: string) {
|
||||
const maybeErrors = this.passwordUpdateForm.get(controlName)?.errors;
|
||||
const maybeError =
|
||||
maybeErrors && (Object.keys(maybeErrors)[0] as errorCode);
|
||||
if (maybeError) {
|
||||
return this.errorTextMap[maybeError];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
newPasswordsMatch: ValidatorFn = (control: AbstractControl) => {
|
||||
if (
|
||||
this.passwordUpdateForm?.get('newPassword')?.value ===
|
||||
this.passwordUpdateForm?.get('newPasswordRepeat')?.value
|
||||
) {
|
||||
this.passwordUpdateForm?.get('newPasswordRepeat')?.setErrors(null);
|
||||
} else {
|
||||
// latest angular just won't detect the error without setTimeout
|
||||
setTimeout(() => {
|
||||
this.passwordUpdateForm
|
||||
?.get('newPasswordRepeat')
|
||||
?.setErrors({ passwordsDontMatch: control.value });
|
||||
});
|
||||
}
|
||||
return null;
|
||||
};
|
||||
static EPP_VALIDATORS = [
|
||||
Validators.required,
|
||||
Validators.minLength(6),
|
||||
Validators.maxLength(16),
|
||||
PasswordInputForm.newPasswordsMatch,
|
||||
];
|
||||
|
||||
passwordUpdateForm = new FormGroup({
|
||||
oldPassword: new FormControl('', [Validators.required]),
|
||||
newPassword: new FormControl('', [
|
||||
Validators.required,
|
||||
Validators.minLength(6),
|
||||
Validators.maxLength(16),
|
||||
this.newPasswordsMatch,
|
||||
]),
|
||||
newPasswordRepeat: new FormControl('', [
|
||||
Validators.required,
|
||||
Validators.minLength(6),
|
||||
Validators.maxLength(16),
|
||||
this.newPasswordsMatch,
|
||||
]),
|
||||
newPassword: new FormControl('', EppPasswordEditComponent.EPP_VALIDATORS),
|
||||
newPasswordRepeat: new FormControl(
|
||||
'',
|
||||
EppPasswordEditComponent.EPP_VALIDATORS
|
||||
),
|
||||
});
|
||||
|
||||
save() {
|
||||
const { oldPassword, newPassword, newPasswordRepeat } =
|
||||
this.passwordUpdateForm.value;
|
||||
if (!oldPassword || !newPassword || !newPasswordRepeat) return;
|
||||
constructor(
|
||||
public registrarService: RegistrarService,
|
||||
public securityService: SecurityService,
|
||||
protected userDataService: UserDataService,
|
||||
private backendService: BackendService,
|
||||
private resetPasswordDialog: MatDialog,
|
||||
private _snackBar: MatSnackBar
|
||||
) {}
|
||||
|
||||
save(passwordResults: PasswordResults) {
|
||||
this.securityService
|
||||
.saveEppPassword({
|
||||
registrarId: this.registrarService.registrarId(),
|
||||
oldPassword,
|
||||
newPassword,
|
||||
newPasswordRepeat,
|
||||
oldPassword: passwordResults.oldPassword!,
|
||||
newPassword: passwordResults.newPassword,
|
||||
newPasswordRepeat: passwordResults.newPasswordRepeat,
|
||||
})
|
||||
.subscribe({
|
||||
complete: () => {
|
||||
@@ -120,4 +108,26 @@ export default class EppPasswordEditComponent {
|
||||
goBack() {
|
||||
this.securityService.isEditingPassword = false;
|
||||
}
|
||||
|
||||
sendEppPasswordResetRequest() {
|
||||
return this.backendService.requestEppPasswordReset(
|
||||
this.registrarService.registrarId()
|
||||
);
|
||||
}
|
||||
|
||||
requestEppPasswordReset() {
|
||||
const dialogRef = this.resetPasswordDialog.open(ResetEppPasswordComponent);
|
||||
dialogRef
|
||||
.afterClosed()
|
||||
.pipe(
|
||||
take(1),
|
||||
filter((result) => !!result)
|
||||
)
|
||||
.pipe(switchMap((_) => this.sendEppPasswordResetRequest()))
|
||||
.subscribe({
|
||||
next: (_) => this.goBack(),
|
||||
error: (err: HttpErrorResponse) =>
|
||||
this._snackBar.open(err.error || err.message),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
<form
|
||||
(ngSubmit)="save()"
|
||||
[formGroup]="formGroup()!"
|
||||
class="console-app__password-input-form"
|
||||
>
|
||||
@if (displayOldPasswordField()) {
|
||||
<div class="console-app__password-input-form-field">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Old password: </mat-label>
|
||||
<input
|
||||
matInput
|
||||
type="text"
|
||||
formControlName="oldPassword"
|
||||
required
|
||||
autocomplete="current-password"
|
||||
/>
|
||||
<mat-error *ngIf="hasError('oldPassword') as errorText">{{
|
||||
errorText
|
||||
}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
}
|
||||
<div class="console-app__password-input-form-field">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>New password: </mat-label>
|
||||
<input
|
||||
matInput
|
||||
type="text"
|
||||
formControlName="newPassword"
|
||||
required
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
<mat-error *ngIf="hasError('newPassword') as errorText">{{
|
||||
errorText
|
||||
}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="console-app__password-input-form-field">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Confirm new password: </mat-label>
|
||||
<input
|
||||
matInput
|
||||
type="text"
|
||||
formControlName="newPasswordRepeat"
|
||||
required
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
<mat-error *ngIf="hasError('newPasswordRepeat') as errorText">{{
|
||||
errorText
|
||||
}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<button
|
||||
mat-flat-button
|
||||
color="primary"
|
||||
[disabled]="!formGroup()?.valid"
|
||||
aria-label="Save new password"
|
||||
type="submit"
|
||||
class="console-app__password-input-form-save"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</form>
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright 2025 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.
|
||||
|
||||
.console-app__password-input-form {
|
||||
max-width: 450px;
|
||||
&-field {
|
||||
width: 100%;
|
||||
mat-form-field {
|
||||
margin-bottom: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
&-form {
|
||||
margin-top: 30px;
|
||||
}
|
||||
&-save {
|
||||
margin-top: 30px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
// Copyright 2025 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.
|
||||
|
||||
import { Component, EventEmitter, input, Output } from '@angular/core';
|
||||
import { AbstractControl, FormGroup, ValidatorFn } from '@angular/forms';
|
||||
|
||||
type errorCode = 'required' | 'maxlength' | 'minlength' | 'passwordsDontMatch';
|
||||
|
||||
type errorFriendlyText = { [type in errorCode]: String };
|
||||
|
||||
export interface PasswordResults {
|
||||
oldPassword: string | null;
|
||||
newPassword: string;
|
||||
newPasswordRepeat: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'password-input-form-component',
|
||||
templateUrl: './passwordInputForm.component.html',
|
||||
styleUrls: ['./passwordInputForm.component.scss'],
|
||||
standalone: false,
|
||||
})
|
||||
export class PasswordInputForm {
|
||||
static newPasswordsMatch: ValidatorFn = (control: AbstractControl) => {
|
||||
const parent = control.parent;
|
||||
if (
|
||||
parent?.get('newPassword')?.value ===
|
||||
parent?.get('newPasswordRepeat')?.value
|
||||
) {
|
||||
parent?.get('newPasswordRepeat')?.setErrors(null);
|
||||
} else {
|
||||
// latest angular just won't detect the error without setTimeout
|
||||
setTimeout(() => {
|
||||
parent
|
||||
?.get('newPasswordRepeat')
|
||||
?.setErrors({ passwordsDontMatch: control.value });
|
||||
});
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
MIN_MAX_LENGTH = 'Passwords must be between 6 and 16 alphanumeric characters';
|
||||
|
||||
errorTextMap: errorFriendlyText = {
|
||||
required: "This field can't be empty",
|
||||
maxlength: this.MIN_MAX_LENGTH,
|
||||
minlength: this.MIN_MAX_LENGTH,
|
||||
passwordsDontMatch: "Passwords don't match",
|
||||
};
|
||||
|
||||
displayOldPasswordField = input<boolean>(false);
|
||||
formGroup = input<FormGroup>();
|
||||
@Output() submitResults = new EventEmitter<PasswordResults>();
|
||||
|
||||
hasError(controlName: string) {
|
||||
const maybeErrors = this.formGroup()!.get(controlName)?.errors;
|
||||
const maybeError =
|
||||
maybeErrors && (Object.keys(maybeErrors)[0] as errorCode);
|
||||
if (maybeError) {
|
||||
return this.errorTextMap[maybeError];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
save() {
|
||||
const results: PasswordResults = this.formGroup()!.value;
|
||||
if (this.displayOldPasswordField() && !results.oldPassword) return;
|
||||
if (!results.newPassword || !results.newPasswordRepeat) return;
|
||||
this.submitResults.emit(results);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<p>
|
||||
<button mat-icon-button aria-label="Go home" [routerLink]="['']">
|
||||
<mat-icon>arrow_back</mat-icon>
|
||||
</button>
|
||||
</p>
|
||||
@if (isLoading) {
|
||||
<div class="console-app__password-reset-verify-spinner">
|
||||
<mat-spinner />
|
||||
</div>
|
||||
} @else if (errorMessage) {
|
||||
<h1 class="mat-headline-4">Failure</h1>
|
||||
<div class="console-app__password-reset-content">
|
||||
<div class="console-app__password-reset-subhead">
|
||||
An error occurred: {{ errorMessage }}.<br /><br />Please double-check the
|
||||
verification code and try again.
|
||||
</div>
|
||||
</div>
|
||||
} @else {
|
||||
<div class="console-app__password-reset-verify">
|
||||
<h1 class="mat-headline-4">{{ type }} password reset</h1>
|
||||
<password-input-form-component
|
||||
[displayOldPasswordField]="false"
|
||||
[formGroup]="passwordUpdateForm!"
|
||||
(submitResults)="save($event)"
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
// Copyright 2025 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.
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
import { ActivatedRoute, ParamMap, Router } from '@angular/router';
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { take } from 'rxjs';
|
||||
import { RegistrarService } from 'src/app/registrar/registrar.service';
|
||||
import { BackendService } from '../../services/backend.service';
|
||||
import { FormControl, FormGroup, Validators } from '@angular/forms';
|
||||
import {
|
||||
PasswordInputForm,
|
||||
PasswordResults,
|
||||
} from './passwordInputForm.component';
|
||||
import EppPasswordEditComponent from 'src/app/settings/security/eppPasswordEdit.component';
|
||||
|
||||
export interface PasswordResetVerifyResponse {
|
||||
registrarId: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-password-reset-verify',
|
||||
templateUrl: './passwordResetVerify.component.html',
|
||||
standalone: false,
|
||||
})
|
||||
export class PasswordResetVerifyComponent {
|
||||
public static PATH = 'password-reset-verify';
|
||||
|
||||
REGISTRY_LOCK_PASSWORD_VALIDATORS = [
|
||||
Validators.required,
|
||||
PasswordInputForm.newPasswordsMatch,
|
||||
];
|
||||
|
||||
isLoading = true;
|
||||
type?: string;
|
||||
errorMessage?: string;
|
||||
requestVerificationCode = '';
|
||||
|
||||
passwordUpdateForm: FormGroup<any> | null = null;
|
||||
|
||||
constructor(
|
||||
protected backendService: BackendService,
|
||||
protected registrarService: RegistrarService,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.route.queryParamMap.pipe(take(1)).subscribe((params: ParamMap) => {
|
||||
this.requestVerificationCode =
|
||||
params.get('resetRequestVerificationCode') || '';
|
||||
this.backendService
|
||||
.getPasswordResetInformation(this.requestVerificationCode)
|
||||
.subscribe({
|
||||
error: (err: HttpErrorResponse) => {
|
||||
this.isLoading = false;
|
||||
this.errorMessage = err.error;
|
||||
},
|
||||
next: this.presentData.bind(this),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
presentData(verificationResponse: PasswordResetVerifyResponse) {
|
||||
this.type = verificationResponse.type === 'EPP' ? 'EPP' : 'Registry lock';
|
||||
this.registrarService.registrarId.set(verificationResponse.registrarId);
|
||||
const validators =
|
||||
verificationResponse.type === 'EPP'
|
||||
? EppPasswordEditComponent.EPP_VALIDATORS
|
||||
: this.REGISTRY_LOCK_PASSWORD_VALIDATORS;
|
||||
|
||||
this.passwordUpdateForm = new FormGroup({
|
||||
newPassword: new FormControl('', validators),
|
||||
newPasswordRepeat: new FormControl('', validators),
|
||||
});
|
||||
this.isLoading = false;
|
||||
}
|
||||
|
||||
save(passwordResults: PasswordResults) {
|
||||
this.backendService
|
||||
.finalizePasswordReset(
|
||||
this.requestVerificationCode,
|
||||
passwordResults.newPassword
|
||||
)
|
||||
.subscribe({
|
||||
error: (err: HttpErrorResponse) => {
|
||||
this.isLoading = false;
|
||||
this.errorMessage = err.error;
|
||||
},
|
||||
next: (_) => this.router.navigate(['']),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
import { Contact } from '../../settings/contact/contact.service';
|
||||
import { EppPasswordBackendModel } from '../../settings/security/security.service';
|
||||
import { UserData } from './userData.service';
|
||||
import { PasswordResetVerifyResponse } from '../components/passwordReset/passwordResetVerify.component';
|
||||
|
||||
@Injectable()
|
||||
export class BackendService {
|
||||
@@ -291,4 +292,26 @@ export class BackendService {
|
||||
registryLockEmail,
|
||||
});
|
||||
}
|
||||
|
||||
requestEppPasswordReset(registrarId: string) {
|
||||
return this.http.post('/console-api/password-reset-request', {
|
||||
type: 'EPP',
|
||||
registrarId,
|
||||
});
|
||||
}
|
||||
|
||||
getPasswordResetInformation(
|
||||
verificationCode: string
|
||||
): Observable<PasswordResetVerifyResponse> {
|
||||
return this.http.get<PasswordResetVerifyResponse>(
|
||||
`/console-api/password-reset-verify?resetRequestVerificationCode=${verificationCode}`
|
||||
);
|
||||
}
|
||||
|
||||
finalizePasswordReset(verificationCode: string, newPassword: string) {
|
||||
return this.http.post(
|
||||
`/console-api/password-reset-verify?resetRequestVerificationCode=${verificationCode}`,
|
||||
newPassword
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import { RegistrarService } from '../registrar/registrar.service';
|
||||
import { SnackBarModule } from '../snackbar.module';
|
||||
import { UserDetailsComponent } from './userDetails.component';
|
||||
import { User, UsersService } from './users.service';
|
||||
import { UserDataService } from '../shared/services/userData.service';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { UsersListComponent } from './usersList.component';
|
||||
import { MatSelectChange } from '@angular/material/select';
|
||||
@@ -55,7 +54,6 @@ export class UsersComponent {
|
||||
constructor(
|
||||
protected registrarService: RegistrarService,
|
||||
protected usersService: UsersService,
|
||||
private userDataService: UserDataService,
|
||||
private _snackBar: MatSnackBar
|
||||
) {
|
||||
effect(() => {
|
||||
|
||||
@@ -58,6 +58,8 @@ def fragileTestPatterns = [
|
||||
// Changes cache timeouts and for some reason appears to have contention
|
||||
// with other tests.
|
||||
"google/registry/whois/WhoisCommandFactoryTest.*",
|
||||
// Breaks random other tests when running with standardTests.
|
||||
"google/registry/bsa/UploadBsaUnavailableDomainsActionTest.*",
|
||||
// Currently changes a global configuration parameter that for some reason
|
||||
// results in timestamp inversions for other tests. TODO(mmuller): fix.
|
||||
"google/registry/flows/host/HostInfoFlowTest.*",
|
||||
@@ -272,7 +274,6 @@ dependencies {
|
||||
testImplementation deps['org.hamcrest:hamcrest']
|
||||
testImplementation deps['org.hamcrest:hamcrest-core']
|
||||
testImplementation deps['org.hamcrest:hamcrest-library']
|
||||
testImplementation deps['junit:junit']
|
||||
testImplementation deps['org.junit.jupiter:junit-jupiter-api']
|
||||
testImplementation deps['org.junit.jupiter:junit-jupiter-engine']
|
||||
testImplementation deps['org.junit.jupiter:junit-jupiter-migrationsupport']
|
||||
|
||||
@@ -4,20 +4,19 @@
|
||||
aopalliance:aopalliance:1.0=annotationProcessor,compileClasspath,deploy_jar,errorprone,nonprodAnnotationProcessor,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,soy,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath
|
||||
args4j:args4j:2.33=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,soy,testCompileClasspath,testRuntimeClasspath
|
||||
com.charleskorn.kaml:kaml:0.20.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson.core:jackson-annotations:2.18.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson.core:jackson-core:2.18.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson.core:jackson-databind:2.18.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson.dataformat:jackson-dataformat-toml:2.18.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.18.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson.datatype:jackson-datatype-joda:2.18.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.18.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson:jackson-bom:2.18.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson.core:jackson-annotations:2.20-rc1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson.core:jackson-core:2.20.0-rc1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson.core:jackson-databind:2.20.0-rc1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.20.0-rc1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson.datatype:jackson-datatype-joda:2.20.0-rc1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.20.0-rc1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson:jackson-bom:2.20.0-rc1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml:classmate:1.5.1=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.github.ben-manes.caffeine:caffeine:3.0.5=annotationProcessor,errorprone,nonprodAnnotationProcessor,testAnnotationProcessor
|
||||
com.github.ben-manes.caffeine:caffeine:3.2.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.docker-java:docker-java-api:3.4.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.docker-java:docker-java-transport-zerodep:3.4.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.docker-java:docker-java-transport:3.4.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.ben-manes.caffeine:caffeine:3.2.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.docker-java:docker-java-api:3.4.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.docker-java:docker-java-transport-zerodep:3.4.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.docker-java:docker-java-transport:3.4.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.jnr:jffi:1.3.13=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.jnr:jnr-a64asm:1.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.jnr:jnr-constants:0.10.4=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
@@ -32,85 +31,80 @@ com.google.api-client:google-api-client-jackson2:2.0.1=compileClasspath,nonprodC
|
||||
com.google.api-client:google-api-client-jackson2:2.7.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,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.7.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.api-client:google-api-client-servlet:2.7.2=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.api-client:google-api-client:2.7.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api-client:google-api-client-servlet:2.8.1=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.api-client:google-api-client:2.8.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:gapic-google-cloud-storage-v2:2.44.1-beta=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:gapic-google-cloud-storage-v2:2.50.0=testCompileClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1:3.11.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.183.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta2:0.183.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-v2:2.51.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-pubsub-v1:1.118.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-pubsublite-v1:1.15.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-spanner-admin-database-v1:6.85.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-spanner-admin-instance-v1:6.85.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-spanner-v1:6.85.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:gapic-google-cloud-storage-v2:2.55.0=testCompileClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1:3.15.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.187.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta2:0.187.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-v2:2.60.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-pubsub-v1:1.122.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-pubsublite-v1:1.15.9=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-spanner-admin-database-v1:6.95.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-spanner-admin-instance-v1:6.95.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-spanner-v1:6.95.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-storage-control-v2:2.44.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-storage-v2:2.44.1-beta=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-storage-v2:2.50.0=testCompileClasspath
|
||||
com.google.api.grpc:grpc-google-common-protos:2.50.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1:3.11.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1alpha:3.11.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1beta1:0.183.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1beta2:0.183.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-bigtable-admin-v2:2.51.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-bigtable-v2:2.51.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-compute-v1:1.69.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-datastore-v1:0.116.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-firestore-v1:3.30.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-monitoring-v3:3.57.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-pubsub-v1:1.118.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-pubsublite-v1:1.15.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-storage-v2:2.55.0=testCompileClasspath
|
||||
com.google.api.grpc:grpc-google-common-protos:2.58.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1:3.15.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1alpha:3.15.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1beta1:0.187.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1beta2:0.187.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1beta:3.15.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-bigtable-admin-v2:2.60.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-bigtable-v2:2.60.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-compute-v1:1.82.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-datastore-v1:0.120.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-firestore-v1:3.31.6=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-monitoring-v3:3.65.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-pubsub-v1:1.122.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-pubsublite-v1:1.15.9=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-secretmanager-v1:2.51.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-secretmanager-v1:2.59.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.api.grpc:proto-google-cloud-secretmanager-v1beta1:2.59.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.api.grpc:proto-google-cloud-secretmanager-v1:2.72.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.api.grpc:proto-google-cloud-secretmanager-v1beta1:2.72.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.api.grpc:proto-google-cloud-secretmanager-v1beta2:2.51.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-secretmanager-v1beta2:2.59.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.api.grpc:proto-google-cloud-spanner-admin-database-v1:6.85.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-spanner-admin-instance-v1:6.85.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-spanner-v1:6.85.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-secretmanager-v1beta2:2.72.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.api.grpc:proto-google-cloud-spanner-admin-database-v1:6.95.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-spanner-admin-instance-v1:6.95.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-spanner-v1:6.95.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-storage-control-v2:2.44.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-storage-v2:2.44.1-beta=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-storage-v2:2.50.0=testCompileClasspath
|
||||
com.google.api.grpc:proto-google-cloud-storage-v2:2.55.0=testCompileClasspath
|
||||
com.google.api.grpc:proto-google-cloud-tasks-v2:2.51.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-tasks-v2:2.59.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.api.grpc:proto-google-cloud-tasks-v2:2.72.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.api.grpc:proto-google-cloud-tasks-v2beta2:0.141.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-tasks-v2beta2:0.149.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.api.grpc:proto-google-cloud-tasks-v2beta2:0.162.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.api.grpc:proto-google-cloud-tasks-v2beta3:0.141.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-tasks-v2beta3:0.149.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.api.grpc:proto-google-common-protos:2.53.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-common-protos:2.54.1=testCompileClasspath
|
||||
com.google.api.grpc:proto-google-iam-v1:1.45.1=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-iam-v1:1.48.0=compileClasspath,nonprodCompileClasspath
|
||||
com.google.api.grpc:proto-google-iam-v1:1.49.1=testCompileClasspath
|
||||
com.google.api:api-common:2.45.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.api:api-common:2.46.1=testCompileClasspath
|
||||
com.google.api:gax-grpc:2.59.1=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.api:gax-grpc:2.62.0=compileClasspath,nonprodCompileClasspath
|
||||
com.google.api:gax-grpc:2.63.1=testCompileClasspath
|
||||
com.google.api:gax-httpjson:2.62.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.api:gax-httpjson:2.63.1=testCompileClasspath
|
||||
com.google.api:gax:2.62.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.api:gax:2.63.1=testCompileClasspath
|
||||
com.google.apis:google-api-services-admin-directory:directory_v1-rev20250217-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-bigquery:v2-rev20241222-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-tasks-v2beta3:0.162.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.api.grpc:proto-google-common-protos:2.60.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-iam-v1:1.53.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-iam-v1:1.55.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.api:api-common:2.52.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api:gax-grpc:2.67.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.api:gax-grpc:2.69.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.api:gax-httpjson:2.69.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api:gax:2.69.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-admin-directory:directory_v1-rev20250804-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-bigquery:v2-rev20250511-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-rev20250310-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-dns:v1-rev20250227-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-drive:v3-rev20250220-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-gmail:v1-rev20240520-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-dataflow:v1b3-rev20250812-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-dns:v1-rev20250411-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-drive:v3-rev20250723-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-gmail:v1-rev20250630-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-groupssettings:v1-rev20220614-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-rev20250213-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-iam:v2-rev20250502-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-rev20250227-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-monitoring:v3-rev20250731-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-rev20250211-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-sqladmin:v1beta4-rev20250205-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-storage:v1-rev20241206-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-storage:v1-rev20250224-2.0.0=testCompileClasspath
|
||||
com.google.auth:google-auth-library-credentials:1.33.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.auth:google-auth-library-oauth2-http:1.33.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-sheets:v4-rev20250616-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-sqladmin:v1beta4-rev20250613-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-storage:v1-rev20250524-2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-storage:v1-rev20250718-2.0.0=testCompileClasspath
|
||||
com.google.auth:google-auth-library-credentials:1.37.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.auth:google-auth-library-oauth2-http:1.37.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.auto.service:auto-service-annotations:1.0.1=errorprone,nonprodAnnotationProcessor,testAnnotationProcessor
|
||||
com.google.auto.service:auto-service-annotations:1.1.1=annotationProcessor,compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.auto.service:auto-service:1.1.1=annotationProcessor
|
||||
@@ -121,50 +115,51 @@ com.google.auto:auto-common:1.2.1=annotationProcessor,errorprone,nonprodAnnotati
|
||||
com.google.cloud.bigdataoss:gcsio:2.2.26=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud.bigdataoss:util:2.2.26=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.25.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud.datastore:datastore-v1-proto-client:2.29.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud.opentelemetry:detector-resources-support:0.33.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud.opentelemetry:exporter-metrics:0.33.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud.opentelemetry:shared-resourcemapping:0.33.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.cloud.sql:jdbc-socket-factory-core:1.23.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud.sql:postgres-socket-factory:1.23.1=deploy_jar,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-bigquerystorage:3.11.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-bigtable:2.51.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-compute:1.69.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-core-grpc:2.49.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-core-grpc:2.53.1=testCompileClasspath
|
||||
com.google.cloud.sql:jdbc-socket-factory-core:1.25.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud.sql:postgres-socket-factory:1.25.3=deploy_jar,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-bigquerystorage:3.15.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-bigtable:2.60.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-compute:1.82.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-core-grpc:2.57.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-core-grpc:2.59.0=testCompileClasspath
|
||||
com.google.cloud:google-cloud-core-http:2.47.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-core-http:2.53.1=testCompileClasspath
|
||||
com.google.cloud:google-cloud-core:2.49.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-core:2.53.1=testCompileClasspath
|
||||
com.google.cloud:google-cloud-firestore:3.30.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-monitoring:3.57.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-core-http:2.59.0=testCompileClasspath
|
||||
com.google.cloud:google-cloud-core:2.57.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-core:2.59.0=testCompileClasspath
|
||||
com.google.cloud:google-cloud-firestore:3.31.6=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-monitoring:3.65.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-nio:0.127.24=testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-nio:0.127.33=testCompileClasspath
|
||||
com.google.cloud:google-cloud-pubsub:1.136.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-pubsublite:1.15.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-nio:0.128.2=testCompileClasspath
|
||||
com.google.cloud:google-cloud-pubsub:1.140.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-pubsublite:1.15.9=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-secretmanager:2.51.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-secretmanager:2.59.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.cloud:google-cloud-spanner:6.85.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-secretmanager:2.72.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.cloud:google-cloud-spanner:6.95.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-storage-control:2.44.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-storage:2.44.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-storage:2.50.0=testCompileClasspath
|
||||
com.google.cloud:google-cloud-storage:2.55.0=testCompileClasspath
|
||||
com.google.cloud:google-cloud-tasks:2.51.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-tasks:2.59.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.cloud:google-cloud-tasks:2.72.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.cloud:grpc-gcp:1.6.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:libraries-bom:26.48.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.cloud:proto-google-cloud-firestore-bundle-v1:3.30.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:proto-google-cloud-firestore-bundle-v1:3.31.6=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
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=soy
|
||||
com.google.code.gson:gson:2.12.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.common.html.types:types:1.0.8=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,soy,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.dagger:dagger-compiler:2.55=annotationProcessor,testAnnotationProcessor
|
||||
com.google.dagger:dagger-spi:2.55=annotationProcessor,testAnnotationProcessor
|
||||
com.google.dagger:dagger:2.55=annotationProcessor,compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.devtools.ksp:symbol-processing-api:2.0.21-1.0.28=annotationProcessor,testAnnotationProcessor
|
||||
com.google.dagger:dagger-compiler:2.57.1=annotationProcessor,testAnnotationProcessor
|
||||
com.google.dagger:dagger-spi:2.57.1=annotationProcessor,testAnnotationProcessor
|
||||
com.google.dagger:dagger:2.57=deploy_jar
|
||||
com.google.dagger:dagger:2.57.1=annotationProcessor,compileClasspath,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.devtools.ksp:symbol-processing-api:2.1.21-2.0.2=annotationProcessor,testAnnotationProcessor
|
||||
com.google.errorprone:error_prone_annotation:2.23.0=annotationProcessor,errorprone,nonprodAnnotationProcessor,testAnnotationProcessor
|
||||
com.google.errorprone:error_prone_annotations:2.20.0=soy
|
||||
com.google.errorprone:error_prone_annotations:2.23.0=annotationProcessor,errorprone,nonprodAnnotationProcessor,testAnnotationProcessor
|
||||
com.google.errorprone:error_prone_annotations:2.36.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.errorprone:error_prone_annotations:2.41.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.errorprone:error_prone_annotations:2.7.1=checkstyle
|
||||
com.google.errorprone:error_prone_check_api:2.23.0=annotationProcessor,errorprone,nonprodAnnotationProcessor,testAnnotationProcessor
|
||||
com.google.errorprone:error_prone_core:2.23.0=annotationProcessor,errorprone,nonprodAnnotationProcessor,testAnnotationProcessor
|
||||
@@ -181,25 +176,25 @@ com.google.flogger:google-extensions:0.7.4=soy
|
||||
com.google.flogger:google-extensions:0.8=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.googlejavaformat:google-java-format:1.5=annotationProcessor,testAnnotationProcessor
|
||||
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:failureaccess:1.0.2=annotationProcessor,testAnnotationProcessor
|
||||
com.google.guava:failureaccess:1.0.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.guava:guava-parent:32.1.1-jre=errorprone,nonprodAnnotationProcessor,soy
|
||||
com.google.guava:guava-testlib:33.3.0-jre=testRuntimeClasspath
|
||||
com.google.guava:guava-testlib:33.4.0-jre=testCompileClasspath
|
||||
com.google.guava:guava-testlib:33.4.8-jre=testCompileClasspath
|
||||
com.google.guava:guava:31.0.1-jre=checkstyle
|
||||
com.google.guava:guava:32.1.1-jre=errorprone,nonprodAnnotationProcessor,soy
|
||||
com.google.guava:guava:33.0.0-jre=annotationProcessor,testAnnotationProcessor
|
||||
com.google.guava:guava:33.4.0-jre=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.guava:guava:33.4.8-jre=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=annotationProcessor,checkstyle,compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,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.45.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.http-client:google-http-client-apache-v2:1.46.3=testCompileClasspath
|
||||
com.google.http-client:google-http-client-apache-v2:2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.http-client:google-http-client-appengine:1.45.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.http-client:google-http-client-appengine:1.46.3=testCompileClasspath
|
||||
com.google.http-client:google-http-client-gson:1.46.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.http-client:google-http-client-appengine:1.47.1=testCompileClasspath
|
||||
com.google.http-client:google-http-client-gson:2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.http-client:google-http-client-jackson2:1.45.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.http-client:google-http-client-jackson2:1.46.3=testCompileClasspath
|
||||
com.google.http-client:google-http-client-protobuf:1.45.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.http-client:google-http-client:1.46.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.http-client:google-http-client-jackson2:1.47.1=testCompileClasspath
|
||||
com.google.http-client:google-http-client-protobuf:1.47.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.http-client:google-http-client:2.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.inject:guice:5.1.0=annotationProcessor,errorprone,nonprodAnnotationProcessor,testAnnotationProcessor
|
||||
com.google.inject:guice:7.0.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,soy,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.j2objc:j2objc-annotations:1.3=checkstyle
|
||||
@@ -215,13 +210,12 @@ com.google.oauth-client:google-oauth-client-jetty:1.36.0=deploy_jar,nonprodRunti
|
||||
com.google.oauth-client:google-oauth-client-jetty:1.39.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.36.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.39.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.oauth-client:google-oauth-client:1.37.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
com.google.oauth-client:google-oauth-client:1.39.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
com.google.protobuf:protobuf-java-util:4.29.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.oauth-client:google-oauth-client:1.39.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.protobuf:protobuf-java-util:4.29.4=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.protobuf:protobuf-java:3.19.6=annotationProcessor,errorprone,nonprodAnnotationProcessor,testAnnotationProcessor
|
||||
com.google.protobuf:protobuf-java:3.21.7=soy
|
||||
com.google.protobuf:protobuf-java:3.25.6=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.re2j:re2j:1.7=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.protobuf:protobuf-java:3.25.8=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.re2j:re2j:1.8=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.template:soy:2024-02-26=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,soy,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.truth:truth:1.4.4=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.googlecode.json-simple:json-simple:1.1.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
@@ -255,11 +249,12 @@ com.sun.istack:istack-commons-tools:4.1.2=jaxb
|
||||
com.sun.xml.bind.external:relaxng-datatype:4.0.5=jaxb
|
||||
com.sun.xml.bind.external:rngom:4.0.5=jaxb
|
||||
com.sun.xml.dtd-parser:dtd-parser:1.5.1=jaxb
|
||||
com.zaxxer:HikariCP:6.2.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.zaxxer:HikariCP:7.0.1=deploy_jar
|
||||
com.zaxxer:HikariCP:7.0.2=compileClasspath,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
commons-beanutils:commons-beanutils:1.9.4=checkstyle
|
||||
commons-codec:commons-codec:1.18.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
commons-codec:commons-codec:1.19.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
commons-collections:commons-collections:3.2.2=checkstyle
|
||||
commons-io:commons-io:2.18.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
commons-io:commons-io:2.20.0=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.6.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
guru.nidi.com.eclipsesource.j2v8:j2v8_linux_x86_64:4.6.0=testRuntimeClasspath
|
||||
@@ -274,37 +269,27 @@ io.apicurio:apicurio-registry-protobuf-schema-utilities:3.0.0.M2=compileClasspat
|
||||
io.github.classgraph:classgraph:4.8.162=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.github.eisop:dataflow-errorprone:3.34.0-eisop1=annotationProcessor,errorprone,nonprodAnnotationProcessor,testAnnotationProcessor
|
||||
io.github.java-diff-utils:java-diff-utils:4.12=annotationProcessor,errorprone,nonprodAnnotationProcessor,testAnnotationProcessor
|
||||
io.github.java-diff-utils:java-diff-utils:4.15=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-alts:1.69.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-alts:1.70.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
io.grpc:grpc-api:1.70.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-auth:1.69.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-auth:1.70.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
io.grpc:grpc-census:1.69.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-context:1.70.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-core:1.69.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-core:1.70.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
io.grpc:grpc-googleapis:1.69.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-grpclb:1.69.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-grpclb:1.70.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
io.grpc:grpc-inprocess:1.69.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-inprocess:1.70.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
io.grpc:grpc-netty-shaded:1.69.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-netty-shaded:1.70.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
io.grpc:grpc-netty:1.69.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-opentelemetry:1.67.1=compileClasspath,nonprodCompileClasspath
|
||||
io.grpc:grpc-opentelemetry:1.68.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-opentelemetry:1.70.0=testCompileClasspath
|
||||
io.github.java-diff-utils:java-diff-utils:4.16=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-alts:1.71.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-api:1.71.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-auth:1.71.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-census:1.71.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-context:1.71.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-core:1.71.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-googleapis:1.71.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-grpclb:1.71.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-inprocess:1.71.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-netty-shaded:1.71.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-netty:1.71.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-opentelemetry:1.71.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-protobuf-lite:1.67.1=compileClasspath,nonprodCompileClasspath
|
||||
io.grpc:grpc-protobuf-lite:1.69.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-protobuf:1.69.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-protobuf:1.70.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
io.grpc:grpc-rls:1.69.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-services:1.69.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-stub:1.69.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-stub:1.70.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
io.grpc:grpc-util:1.69.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-xds:1.69.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-protobuf-lite:1.71.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-protobuf:1.71.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-rls:1.71.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-services:1.71.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-stub:1.71.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-util:1.71.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-xds:1.71.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.netty:netty-buffer:4.1.110.Final=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.netty:netty-codec-http2:4.1.110.Final=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.netty:netty-codec-http:4.1.110.Final=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
@@ -334,38 +319,29 @@ io.opentelemetry.contrib:opentelemetry-gcp-resources:1.37.0-alpha=compileClasspa
|
||||
io.opentelemetry.instrumentation:opentelemetry-grpc-1.6:2.1.0-alpha=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry.instrumentation:opentelemetry-instrumentation-api-incubator:2.1.0-alpha=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry.instrumentation:opentelemetry-instrumentation-api:2.1.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry.semconv:opentelemetry-semconv:1.27.0-alpha=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
|
||||
io.opentelemetry.semconv:opentelemetry-semconv:1.28.0-alpha=testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-api-incubator:1.45.0-alpha=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath
|
||||
io.opentelemetry:opentelemetry-api-incubator:1.46.0-alpha=testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-api:1.45.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
|
||||
io.opentelemetry:opentelemetry-api:1.46.0=testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-api:1.47.0=testCompileClasspath
|
||||
io.opentelemetry.semconv:opentelemetry-semconv:1.29.0-alpha=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-api-incubator:1.42.1-alpha=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-api:1.47.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
|
||||
io.opentelemetry:opentelemetry-api:1.53.0=testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-bom:1.42.1=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-context:1.45.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
|
||||
io.opentelemetry:opentelemetry-context:1.46.0=testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-context:1.47.0=testCompileClasspath
|
||||
io.opentelemetry:opentelemetry-exporter-logging:1.46.0=testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-common:1.53.0=testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-context:1.47.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
|
||||
io.opentelemetry:opentelemetry-context:1.53.0=testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-exporter-logging:1.53.0=testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-extension-incubator:1.35.0-alpha=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-common:1.45.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-common:1.46.0=testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-common:1.47.0=testCompileClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-common:1.47.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-common:1.53.0=testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:1.42.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:1.46.0=testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:1.47.0=testCompileClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-extension-autoconfigure:1.46.0=testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-logs:1.45.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-logs:1.46.0=testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-logs:1.47.0=testCompileClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-metrics:1.45.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-metrics:1.46.0=testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-metrics:1.47.0=testCompileClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-trace:1.45.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-trace:1.46.0=testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-trace:1.47.0=testCompileClasspath
|
||||
io.opentelemetry:opentelemetry-sdk:1.45.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk:1.46.0=testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk:1.47.0=testCompileClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:1.53.0=testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-extension-autoconfigure:1.53.0=testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-logs:1.47.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-logs:1.53.0=testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-metrics:1.47.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-metrics:1.53.0=testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-trace:1.47.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk-trace:1.53.0=testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk:1.47.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
|
||||
io.opentelemetry:opentelemetry-sdk:1.53.0=testCompileClasspath,testRuntimeClasspath
|
||||
io.opentelemetry:opentelemetry-semconv:1.26.0-alpha=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.outfoxx:swiftpoet:1.3.1=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
io.perfmark:perfmark-api:0.27.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
@@ -387,10 +363,10 @@ javax.validation:validation-api:1.0.0.GA=compileClasspath,deploy_jar,nonprodComp
|
||||
joda-time:joda-time:2.12.7=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.15.11=testCompileClasspath,testRuntimeClasspath
|
||||
net.bytebuddy:byte-buddy-agent:1.17.6=testCompileClasspath,testRuntimeClasspath
|
||||
net.bytebuddy:byte-buddy:1.14.12=compileClasspath,nonprodCompileClasspath
|
||||
net.bytebuddy:byte-buddy:1.14.15=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath
|
||||
net.bytebuddy:byte-buddy:1.15.11=testCompileClasspath,testRuntimeClasspath
|
||||
net.bytebuddy:byte-buddy:1.17.6=testCompileClasspath,testRuntimeClasspath
|
||||
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
|
||||
@@ -404,33 +380,33 @@ org.apache.arrow:arrow-format:15.0.2=compileClasspath,deploy_jar,nonprodCompileC
|
||||
org.apache.arrow:arrow-memory-core:15.0.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.arrow:arrow-vector:15.0.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.avro:avro:1.11.4=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-model-fn-execution:2.63.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-model-job-management:2.63.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-model-pipeline:2.63.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-model-fn-execution:2.67.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-model-job-management:2.67.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-model-pipeline:2.67.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.63.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-runners-direct-java:2.63.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-runners-google-cloud-dataflow-java:2.63.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-runners-java-fn-execution:2.63.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-core:2.63.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-expansion-service:2.63.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-extensions-arrow:2.63.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-extensions-avro:2.63.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core:2.63.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-extensions-protobuf:2.63.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-runners-core-java:2.67.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-runners-direct-java:2.67.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-runners-google-cloud-dataflow-java:2.67.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-runners-java-fn-execution:2.67.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-core:2.67.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-expansion-service:2.67.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-extensions-arrow:2.67.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-extensions-avro:2.67.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core:2.67.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-extensions-protobuf:2.67.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.63.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-io-google-cloud-platform:2.63.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-transform-service-launcher:2.63.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-harness:2.67.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-io-google-cloud-platform:2.67.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-transform-service-launcher:2.67.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-vendor-grpc-1_60_1:0.1=testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-vendor-grpc-1_69_0:0.1=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.26.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.commons:commons-csv:1.13.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.commons:commons-exec:1.4.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.commons:commons-csv:1.14.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.commons:commons-exec:1.5.0=testRuntimeClasspath
|
||||
org.apache.commons:commons-lang3:3.14.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath
|
||||
org.apache.commons:commons-lang3:3.17.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.commons:commons-text:1.13.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.commons:commons-lang3:3.18.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.commons:commons-text:1.14.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.ftpserver:ftplet-api:1.2.1=testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.ftpserver:ftpserver-core:1.2.1=testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.httpcomponents:httpclient:4.5.14=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
@@ -440,37 +416,39 @@ org.apache.sshd:sshd-common:2.15.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.sshd:sshd-core:2.15.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.sshd:sshd-scp:2.15.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.sshd:sshd-sftp:2.15.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.tomcat:tomcat-annotations-api:11.0.5=testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.tomcat:tomcat-annotations-api:11.0.10=testCompileClasspath,testRuntimeClasspath
|
||||
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath
|
||||
org.bouncycastle:bcpg-jdk18on:1.80=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.bouncycastle:bcpkix-jdk18on:1.80=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.bouncycastle:bcprov-jdk18on:1.80=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.bouncycastle:bcutil-jdk18on:1.80=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.checkerframework:checker-compat-qual:2.5.3=compileClasspath,nonprodCompileClasspath,soy,testCompileClasspath
|
||||
org.checkerframework:checker-compat-qual:2.5.5=annotationProcessor,testAnnotationProcessor
|
||||
org.bouncycastle:bcpg-jdk18on:1.81=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.bouncycastle:bcpkix-jdk18on:1.81=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.bouncycastle:bcprov-jdk18on:1.81=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.bouncycastle:bcutil-jdk18on:1.81=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.checkerframework:checker-compat-qual:2.5.3=annotationProcessor,compileClasspath,nonprodCompileClasspath,soy,testAnnotationProcessor,testCompileClasspath
|
||||
org.checkerframework:checker-compat-qual:2.5.6=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
org.checkerframework:checker-qual:3.12.0=checkstyle
|
||||
org.checkerframework:checker-qual:3.33.0=errorprone,nonprodAnnotationProcessor,soy
|
||||
org.checkerframework:checker-qual:3.41.0=annotationProcessor,testAnnotationProcessor
|
||||
org.checkerframework:checker-qual:3.49.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.checkerframework:checker-qual:3.49.0=compileClasspath,nonprodCompileClasspath,testCompileClasspath
|
||||
org.checkerframework:checker-qual:3.49.3=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
org.codehaus.mojo:animal-sniffer-annotations:1.24=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.conscrypt:conscrypt-openjdk-uber:2.5.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.angus:angus-activation:2.0.2=deploy_jar,jaxb,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
org.eclipse.angus:jakarta.mail:2.0.3=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
org.eclipse.angus:jakarta.mail:2.0.4=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
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.1.0.alpha1=testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty.ee10:jetty-ee10-webapp:12.1.0.alpha1=testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-ee:12.1.0.alpha1=testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-http:12.1.0.alpha1=testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-io:12.1.0.alpha1=testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-security:12.1.0.alpha1=testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-server:12.1.0.alpha1=testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-session:12.1.0.alpha1=testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-util:12.1.0.alpha1=testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-xml:12.1.0.alpha1=testCompileClasspath,testRuntimeClasspath
|
||||
org.flywaydb:flyway-core:11.4.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.flywaydb:flyway-database-postgresql:11.4.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty.ee10:jetty-ee10-servlet:12.1.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty.ee10:jetty-ee10-webapp:12.1.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty.ee:jetty-ee-webapp:12.1.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-http:12.1.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-io:12.1.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-security:12.1.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-server:12.1.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-session:12.1.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-util:12.1.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-xml:12.1.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.flywaydb:flyway-core:11.11.1=deploy_jar
|
||||
org.flywaydb:flyway-core:11.11.2=compileClasspath,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.flywaydb:flyway-database-postgresql:11.11.1=deploy_jar
|
||||
org.flywaydb:flyway-database-postgresql:11.11.2=compileClasspath,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.glassfish.jaxb:codemodel:4.0.5=jaxb
|
||||
org.glassfish.jaxb:jaxb-core:4.0.2=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
org.glassfish.jaxb:jaxb-core:4.0.5=jaxb
|
||||
@@ -498,6 +476,7 @@ org.javassist:javassist:3.28.0-GA=checkstyle
|
||||
org.jboss.logging:jboss-logging:3.5.0.Final=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
org.jcommander:jcommander:2.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-bom:1.4.0=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-metadata-jvm:2.1.21=annotationProcessor,testAnnotationProcessor
|
||||
org.jetbrains.kotlin:kotlin-reflect:1.6.10=annotationProcessor,testAnnotationProcessor
|
||||
org.jetbrains.kotlin:kotlin-reflect:1.9.20=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.20=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
@@ -506,7 +485,7 @@ org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.10=compileClasspath,deploy_jar,nonpr
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0=annotationProcessor,testAnnotationProcessor
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.10=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.9.20=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.0.21=annotationProcessor,testAnnotationProcessor
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.1.21=annotationProcessor,testAnnotationProcessor
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.2=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.4.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
@@ -515,26 +494,26 @@ 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.29.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.joda:joda-money:2.0.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.jline:jline:3.30.5=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.joda:joda-money:2.0.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.json:json:20230618=soy
|
||||
org.json:json:20250107=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.jsoup:jsoup:1.19.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.jsoup:jsoup:1.21.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.jspecify:jspecify:1.0.0=annotationProcessor,compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath
|
||||
org.junit-pioneer:junit-pioneer:2.3.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-api:5.12.1=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-engine:5.12.1=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-migrationsupport:5.12.1=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-params:5.12.1=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-commons:1.12.1=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-engine:1.12.1=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-launcher:1.12.1=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-runner:1.12.1=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-suite-api:1.12.1=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-suite-commons:1.12.1=testRuntimeClasspath
|
||||
org.junit:junit-bom:5.12.1=testCompileClasspath,testRuntimeClasspath
|
||||
org.mockito:mockito-core:5.16.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.mockito:mockito-junit-jupiter:5.16.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-api:5.13.4=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-engine:5.13.4=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-migrationsupport:5.13.4=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-params:5.13.4=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-commons:1.13.4=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-engine:1.13.4=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-launcher:1.13.4=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-runner:1.13.3=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-suite-api:1.13.4=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-suite-commons:1.13.4=testRuntimeClasspath
|
||||
org.junit:junit-bom:5.13.4=testCompileClasspath,testRuntimeClasspath
|
||||
org.mockito:mockito-core:5.19.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.mockito:mockito-junit-jupiter:5.19.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.objenesis:objenesis:3.3=testRuntimeClasspath
|
||||
org.ogce:xpp3:1.1.6=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath
|
||||
@@ -552,50 +531,58 @@ org.ow2.asm:asm:9.5=soy
|
||||
org.ow2.asm:asm:9.7=jacocoAnt
|
||||
org.ow2.asm:asm:9.7.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.pcollections:pcollections:3.1.4=annotationProcessor,errorprone,nonprodAnnotationProcessor,testAnnotationProcessor
|
||||
org.postgresql:postgresql:42.7.5=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.postgresql:postgresql:42.7.7=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.reflections:reflections:0.10.2=checkstyle
|
||||
org.rnorth.duct-tape:duct-tape:1.0.8=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-api:4.29.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-chrome-driver:4.29.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-chromium-driver:4.29.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-devtools-v131:4.29.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-devtools-v132:4.29.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-devtools-v133:4.29.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-devtools-v85:4.29.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-edge-driver:4.29.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-firefox-driver:4.29.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-http:4.29.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-ie-driver:4.29.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-java:4.29.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-json:4.29.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-manager:4.29.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-os:4.29.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-remote-driver:4.29.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-safari-driver:4.29.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-support:4.29.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-api:4.35.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-chrome-driver:4.35.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-chromium-driver:4.35.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-devtools-v137:4.35.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-devtools-v138:4.35.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-devtools-v139:4.35.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-edge-driver:4.35.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-firefox-driver:4.35.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-http:4.35.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-ie-driver:4.35.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-java:4.35.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-json:4.35.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-manager:4.35.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-os:4.35.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-remote-driver:4.35.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-safari-driver:4.35.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.seleniumhq.selenium:selenium-support:4.35.0=testCompileClasspath,testRuntimeClasspath
|
||||
org.slf4j:jcl-over-slf4j:1.7.36=testCompileClasspath,testRuntimeClasspath
|
||||
org.slf4j:jul-to-slf4j:1.7.30=testRuntimeClasspath
|
||||
org.slf4j:slf4j-api:2.0.16=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.slf4j:slf4j-jdk14:2.0.16=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.slf4j:slf4j-api:2.0.17=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.slf4j:slf4j-jdk14:2.0.17=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.snakeyaml:snakeyaml-engine:2.1=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testRuntimeClasspath
|
||||
org.testcontainers:database-commons:1.20.6=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.testcontainers:jdbc:1.20.6=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.testcontainers:junit-jupiter:1.20.6=testCompileClasspath,testRuntimeClasspath
|
||||
org.testcontainers:postgresql:1.20.6=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.testcontainers:selenium:1.20.6=testCompileClasspath,testRuntimeClasspath
|
||||
org.testcontainers:testcontainers:1.20.6=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.testcontainers:database-commons:1.21.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.testcontainers:jdbc:1.21.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.testcontainers:junit-jupiter:1.21.3=testCompileClasspath,testRuntimeClasspath
|
||||
org.testcontainers:postgresql:1.21.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.testcontainers:selenium:1.21.3=testCompileClasspath,testRuntimeClasspath
|
||||
org.testcontainers:testcontainers:1.21.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.threeten:threetenbp:1.7.0=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
|
||||
org.yaml:snakeyaml:2.3=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
us.fatehi:schemacrawler-api:16.25.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
us.fatehi:schemacrawler-diagram:16.25.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
us.fatehi:schemacrawler-loader:16.25.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
us.fatehi:schemacrawler-postgresql:16.25.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
us.fatehi:schemacrawler-text:16.25.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
us.fatehi:schemacrawler-tools:16.25.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
us.fatehi:schemacrawler-utility:16.25.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
us.fatehi:schemacrawler:16.25.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.yaml:snakeyaml:2.4=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
us.fatehi:schemacrawler-api:16.26.3=deploy_jar
|
||||
us.fatehi:schemacrawler-api:16.27.1=compileClasspath,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
us.fatehi:schemacrawler-diagram:16.26.3=deploy_jar
|
||||
us.fatehi:schemacrawler-diagram:16.27.1=compileClasspath,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
us.fatehi:schemacrawler-loader:16.26.3=deploy_jar
|
||||
us.fatehi:schemacrawler-loader:16.27.1=compileClasspath,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
us.fatehi:schemacrawler-operations:16.27.1=compileClasspath,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
us.fatehi:schemacrawler-postgresql:16.26.3=deploy_jar
|
||||
us.fatehi:schemacrawler-postgresql:16.27.1=compileClasspath,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
us.fatehi:schemacrawler-text:16.26.3=deploy_jar
|
||||
us.fatehi:schemacrawler-text:16.27.1=compileClasspath,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
us.fatehi:schemacrawler-tools:16.26.3=deploy_jar
|
||||
us.fatehi:schemacrawler-tools:16.27.1=compileClasspath,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
us.fatehi:schemacrawler-utility:16.26.3=deploy_jar
|
||||
us.fatehi:schemacrawler-utility:16.27.1=compileClasspath,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
us.fatehi:schemacrawler:16.26.3=deploy_jar
|
||||
us.fatehi:schemacrawler:16.27.1=compileClasspath,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
xerces:xmlParserAPIs:2.6.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
empty=devtool,nomulus_test
|
||||
|
||||
@@ -275,7 +275,7 @@ public class SendExpiringCertificateNotificationEmailAction implements Runnable
|
||||
*/
|
||||
@VisibleForTesting
|
||||
ImmutableSet<InternetAddress> getEmailAddresses(Registrar registrar, Type contactType) {
|
||||
ImmutableSortedSet<RegistrarPoc> contacts = registrar.getContactsOfType(contactType);
|
||||
ImmutableSortedSet<RegistrarPoc> contacts = registrar.getPocsOfType(contactType);
|
||||
ImmutableSet.Builder<InternetAddress> recipientEmails = new ImmutableSet.Builder<>();
|
||||
for (RegistrarPoc contact : contacts) {
|
||||
try {
|
||||
|
||||
@@ -215,10 +215,12 @@ public class BsaValidateAction implements Runnable {
|
||||
if (Objects.equals(expectedReason, domain.reason())) {
|
||||
return Optional.empty();
|
||||
}
|
||||
if (isRegistered || domain.reason().equals(Reason.REGISTERED)) {
|
||||
if (isStalenessAllowed(isRegistered, activeDomains.get(domain.domainName()))) {
|
||||
// Registered name still reported with other reasons: Don't report if registration is recent.
|
||||
// Note that staleness is not tolerated if deregistered name is still reported as registered:
|
||||
// in this case we do not have the VKey on hand, and it is not worth the effort to find it
|
||||
// out.
|
||||
if (isRegistered && isStalenessAllowed(activeDomains.get(domain.domainName()))) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
return Optional.of(
|
||||
String.format(
|
||||
@@ -228,15 +230,10 @@ public class BsaValidateAction implements Runnable {
|
||||
domain.reason()));
|
||||
}
|
||||
|
||||
boolean isStalenessAllowed(boolean isNewDomain, VKey<Domain> domainVKey) {
|
||||
boolean isStalenessAllowed(VKey<Domain> domainVKey) {
|
||||
Domain domain = bsaQuery(() -> replicaTm().loadByKey(domainVKey));
|
||||
var now = clock.nowUtc();
|
||||
if (isNewDomain) {
|
||||
return domain.getCreationTime().plus(maxStaleness).isAfter(now);
|
||||
} else {
|
||||
return domain.getDeletionTime().isBefore(now)
|
||||
&& domain.getDeletionTime().plus(maxStaleness).isAfter(now);
|
||||
}
|
||||
return domain.getCreationTime().plus(maxStaleness).isAfter(now);
|
||||
}
|
||||
|
||||
/** Returns unique labels across all block lists in the download specified by {@code jobName}. */
|
||||
|
||||
@@ -25,16 +25,16 @@ 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 static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.google.cloud.storage.BlobId;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.google.common.hash.Hasher;
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.google.common.io.ByteSource;
|
||||
import google.registry.bsa.api.BsaCredential;
|
||||
import google.registry.config.RegistryConfig.Config;
|
||||
import google.registry.gcs.GcsUtils;
|
||||
@@ -47,10 +47,13 @@ import google.registry.request.auth.Auth;
|
||||
import google.registry.util.Clock;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.persistence.TypedQuery;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PipedInputStream;
|
||||
import java.io.PipedOutputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.Optional;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
@@ -60,14 +63,17 @@ import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
import okio.BufferedSink;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* Daily action that uploads unavailable domain names on applicable TLDs to BSA.
|
||||
*
|
||||
* <p>The upload is a single zipped text file containing combined details for all BSA-enrolled TLDs.
|
||||
* The text is a newline-delimited list of punycoded fully qualified domain names, and contains all
|
||||
* domains on each TLD that are registered and/or reserved.
|
||||
* The text is a newline-delimited list of punycoded fully qualified domain names with a trailing
|
||||
* newline at the end, and contains all domains on each TLD that are registered and/or reserved.
|
||||
*
|
||||
* <p>The file is also uploaded to GCS to preserve it as a record for ourselves.
|
||||
*/
|
||||
@@ -118,7 +124,7 @@ public class UploadBsaUnavailableDomainsAction implements Runnable {
|
||||
// TODO(mcilwain): Implement a date Cursor, have the cronjob run frequently, and short-circuit
|
||||
// the run if the daily upload is already completed.
|
||||
DateTime runTime = clock.nowUtc();
|
||||
String unavailableDomains = Joiner.on("\n").join(getUnavailableDomains(runTime));
|
||||
ImmutableSortedSet<String> unavailableDomains = getUnavailableDomains(runTime);
|
||||
if (unavailableDomains.isEmpty()) {
|
||||
logger.atWarning().log("No unavailable domains found; terminating.");
|
||||
emailSender.sendNotification(
|
||||
@@ -136,12 +142,16 @@ public class UploadBsaUnavailableDomainsAction implements Runnable {
|
||||
}
|
||||
|
||||
/** Uploads the unavailable domains list to GCS in the unavailable domains bucket. */
|
||||
boolean uploadToGcs(String unavailableDomains, DateTime runTime) {
|
||||
boolean uploadToGcs(ImmutableSortedSet<String> unavailableDomains, DateTime runTime) {
|
||||
logger.atInfo().log("Uploading unavailable names file to GCS in bucket %s", gcsBucket);
|
||||
BlobId blobId = BlobId.of(gcsBucket, createFilename(runTime));
|
||||
// `gcsUtils.openOutputStream` returns a buffered stream
|
||||
try (OutputStream gcsOutput = gcsUtils.openOutputStream(blobId);
|
||||
Writer osWriter = new OutputStreamWriter(gcsOutput, US_ASCII)) {
|
||||
osWriter.write(unavailableDomains);
|
||||
for (var domainName : unavailableDomains) {
|
||||
osWriter.write(domainName);
|
||||
osWriter.write("\n");
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
logger.atSevere().withCause(e).log(
|
||||
@@ -150,10 +160,14 @@ public class UploadBsaUnavailableDomainsAction implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
boolean uploadToBsa(String unavailableDomains, DateTime runTime) {
|
||||
boolean uploadToBsa(ImmutableSortedSet<String> unavailableDomains, DateTime runTime) {
|
||||
try {
|
||||
byte[] gzippedContents = gzipUnavailableDomains(unavailableDomains);
|
||||
String sha512Hash = ByteSource.wrap(gzippedContents).hash(Hashing.sha512()).toString();
|
||||
Hasher sha512Hasher = Hashing.sha512().newHasher();
|
||||
unavailableDomains.stream()
|
||||
.map(name -> name + "\n")
|
||||
.forEachOrdered(line -> sha512Hasher.putString(line, UTF_8));
|
||||
String sha512Hash = sha512Hasher.hash().toString();
|
||||
|
||||
String filename = createFilename(runTime);
|
||||
OkHttpClient client = new OkHttpClient().newBuilder().build();
|
||||
|
||||
@@ -169,7 +183,9 @@ public class UploadBsaUnavailableDomainsAction implements Runnable {
|
||||
.addFormDataPart(
|
||||
"file",
|
||||
String.format("%s.gz", filename),
|
||||
RequestBody.create(gzippedContents, MediaType.parse("application/octet-stream")))
|
||||
new StreamingRequestBody(
|
||||
gzippedStream(unavailableDomains),
|
||||
MediaType.parse("application/octet-stream")))
|
||||
.build();
|
||||
|
||||
Request request =
|
||||
@@ -196,15 +212,6 @@ public class UploadBsaUnavailableDomainsAction implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] gzipUnavailableDomains(String unavailableDomains) throws IOException {
|
||||
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
|
||||
try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream)) {
|
||||
gzipOutputStream.write(unavailableDomains.getBytes(US_ASCII));
|
||||
}
|
||||
return byteArrayOutputStream.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
private static String createFilename(DateTime runTime) {
|
||||
return String.format("unavailable_domains_%s.txt", runTime.toString());
|
||||
}
|
||||
@@ -280,4 +287,65 @@ public class UploadBsaUnavailableDomainsAction implements Runnable {
|
||||
private static String toDomain(String domainLabel, Tld tld) {
|
||||
return String.format("%s.%s", domainLabel, tld.getTldStr());
|
||||
}
|
||||
|
||||
private InputStream gzippedStream(ImmutableSortedSet<String> unavailableDomains)
|
||||
throws IOException {
|
||||
PipedInputStream inputStream = new PipedInputStream();
|
||||
PipedOutputStream outputStream = new PipedOutputStream(inputStream);
|
||||
|
||||
new Thread(
|
||||
() -> {
|
||||
try {
|
||||
gzipUnavailableDomains(outputStream, unavailableDomains);
|
||||
} catch (Throwable e) {
|
||||
logger.atSevere().withCause(e).log("Failed to gzip unavailable domains.");
|
||||
try {
|
||||
// This will cause the next read to throw an IOException.
|
||||
inputStream.close();
|
||||
} catch (IOException ignore) {
|
||||
// Won't happen for `PipedInputStream.close()`
|
||||
}
|
||||
}
|
||||
})
|
||||
.start();
|
||||
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
private void gzipUnavailableDomains(
|
||||
PipedOutputStream outputStream, ImmutableSortedSet<String> unavailableDomains)
|
||||
throws IOException {
|
||||
// `GZIPOutputStream` is buffered.
|
||||
try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream)) {
|
||||
for (String name : unavailableDomains) {
|
||||
var line = name + "\n";
|
||||
gzipOutputStream.write(line.getBytes(US_ASCII));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class StreamingRequestBody extends RequestBody {
|
||||
private final BufferedInputStream inputStream;
|
||||
private final MediaType mediaType;
|
||||
|
||||
StreamingRequestBody(InputStream inputStream, MediaType mediaType) {
|
||||
this.inputStream = new BufferedInputStream(inputStream);
|
||||
this.mediaType = mediaType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MediaType contentType() {
|
||||
return mediaType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(@NotNull BufferedSink bufferedSink) throws IOException {
|
||||
byte[] buffer = new byte[2048];
|
||||
int bytesRead;
|
||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||
bufferedSink.write(buffer, 0, bytesRead);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ hibernate:
|
||||
# that BEAM pipelines are not subject to the maximumPoolSize value defined
|
||||
# here. See PersistenceModule.java for more information.
|
||||
hikariMinimumIdle: 1
|
||||
hikariMaximumPoolSize: 20
|
||||
hikariMaximumPoolSize: 40
|
||||
hikariIdleTimeout: 300000
|
||||
# The batch size is basically the number of insertions / updates in a single
|
||||
# transaction that will be batched together into one INSERT/UPDATE statement.
|
||||
@@ -255,7 +255,7 @@ hibernate:
|
||||
# The fetch size is the number of entities retrieved at a time from the
|
||||
# database cursor. Here we set a small default geared toward Nomulus server
|
||||
# transactions. Large queries can override the defaults on a per-query basis.
|
||||
jdbcFetchSize: 20
|
||||
jdbcFetchSize: 40
|
||||
|
||||
cloudSql:
|
||||
# jdbc url for the Cloud SQL database.
|
||||
|
||||
@@ -88,6 +88,7 @@
|
||||
should exist between the RECURRING_BILLING cursor's time and the execution
|
||||
time of the action.
|
||||
</description>
|
||||
<!-- Runs shortly after DeleteExpiredDomainsAction so it can delete domains before they renew -->
|
||||
<schedule>0 3 * * *</schedule>
|
||||
</task>
|
||||
|
||||
@@ -98,7 +99,8 @@
|
||||
This job runs an action that deletes domains that are past their
|
||||
autorenew end date.
|
||||
</description>
|
||||
<schedule>7 3 * * *</schedule>
|
||||
<!-- Runs shortly before ExpandBillingRecurrencesPipeline to catch and delete domains before they renew -->
|
||||
<schedule>45 2 * * *</schedule>
|
||||
</task>
|
||||
|
||||
<task>
|
||||
|
||||
@@ -146,6 +146,7 @@
|
||||
This job runs an action that deletes domains that are past their
|
||||
autorenew end date.
|
||||
</description>
|
||||
<schedule>7 3 * * *</schedule>
|
||||
<!-- Runs shortly before ExpandBillingRecurrencesPipeline to catch and delete domains before they renew -->
|
||||
<schedule>45 2 * * *</schedule>
|
||||
</task>
|
||||
</entries>
|
||||
|
||||
@@ -130,6 +130,7 @@
|
||||
should exist between the RECURRING_BILLING cursor's time and the execution
|
||||
time of the action.
|
||||
</description>
|
||||
<!-- Runs shortly after DeleteExpiredDomainsAction so it can delete domains before they renew -->
|
||||
<schedule>0 3 * * *</schedule>
|
||||
</task>
|
||||
|
||||
@@ -140,7 +141,8 @@
|
||||
This job runs an action that deletes domains that are past their
|
||||
autorenew end date.
|
||||
</description>
|
||||
<schedule>7 3 * * *</schedule>
|
||||
<!-- Runs shortly before ExpandBillingRecurrencesPipeline to catch and delete domains before they renew -->
|
||||
<schedule>45 2 * * *</schedule>
|
||||
</task>
|
||||
|
||||
<task>
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
This job runs an action that deletes domains that are past their
|
||||
autorenew end date.
|
||||
</description>
|
||||
<schedule>7 3 * * *</schedule>
|
||||
<!-- Runs shortly before ExpandBillingRecurrencesPipeline to catch and delete domains before they renew -->
|
||||
<schedule>45 2 * * *</schedule>
|
||||
</task>
|
||||
</entries>
|
||||
|
||||
@@ -90,6 +90,7 @@
|
||||
should exist between the RECURRING_BILLING cursor's time and the execution
|
||||
time of the action.
|
||||
</description>
|
||||
<!-- Runs shortly after DeleteExpiredDomainsAction so it can delete domains before they renew -->
|
||||
<schedule>0 3 * * *</schedule>
|
||||
</task>
|
||||
|
||||
@@ -113,7 +114,8 @@
|
||||
This job runs an action that deletes domains that are past their
|
||||
autorenew end date.
|
||||
</description>
|
||||
<schedule>7 3 * * *</schedule>
|
||||
<!-- Runs shortly before ExpandBillingRecurrencesPipeline to catch and delete domains before they renew -->
|
||||
<schedule>45 2 * * *</schedule>
|
||||
</task>
|
||||
|
||||
<task>
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.google.common.net.MediaType;
|
||||
import google.registry.model.eppoutput.EppOutput;
|
||||
import google.registry.request.Response;
|
||||
import google.registry.util.ProxyHttpHeaders;
|
||||
import google.registry.util.StopwatchLogger;
|
||||
import jakarta.inject.Inject;
|
||||
|
||||
/** Handle an EPP request and response. */
|
||||
@@ -55,7 +56,10 @@ public class EppRequestHandler {
|
||||
eppController.handleEppCommand(
|
||||
sessionMetadata, credentials, eppRequestSource, isDryRun, isSuperuser, inputXmlBytes);
|
||||
response.setContentType(APPLICATION_EPP_XML);
|
||||
final StopwatchLogger stopwatch = new StopwatchLogger();
|
||||
byte[] eppResponseXmlBytes = marshalWithLenientRetry(eppOutput);
|
||||
stopwatch.tick("Completed EPP output marshaling.");
|
||||
|
||||
response.setPayload(new String(eppResponseXmlBytes, UTF_8));
|
||||
logger.atInfo().log(
|
||||
"EPP response: %s", prettyPrint(EppXmlSanitizer.sanitizeEppXml(eppResponseXmlBytes)));
|
||||
|
||||
@@ -29,6 +29,7 @@ import google.registry.model.eppoutput.EppOutput;
|
||||
import google.registry.monitoring.whitebox.EppMetric;
|
||||
import google.registry.persistence.PersistenceModule.TransactionIsolationLevel;
|
||||
import google.registry.persistence.transaction.JpaTransactionManager;
|
||||
import google.registry.util.StopwatchLogger;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Provider;
|
||||
import java.util.Optional;
|
||||
@@ -77,23 +78,32 @@ public class FlowRunner {
|
||||
flowReporter.recordToLogs();
|
||||
}
|
||||
eppMetricBuilder.setCommandNameFromFlow(flowClass.getSimpleName());
|
||||
final StopwatchLogger stopwatch = new StopwatchLogger();
|
||||
|
||||
// We may already be in a transaction, e.g., when invoked by DeleteExpiredDomainsAction.
|
||||
if (!isTransactional || jpaTransactionManager.inTransaction()) {
|
||||
stopwatch.tick("We're in transaction, running the flow now.");
|
||||
return EppOutput.create(flowProvider.get().run());
|
||||
}
|
||||
|
||||
stopwatch.tick("We're not in transaction, calling transact.");
|
||||
try {
|
||||
return jpaTransactionManager.transact(
|
||||
isolationLevelOverride.orElse(null),
|
||||
() -> {
|
||||
try {
|
||||
stopwatch.tick("Running the flow in transaction.");
|
||||
EppOutput output = EppOutput.create(flowProvider.get().run());
|
||||
stopwatch.tick("Completed the flow in transaction.");
|
||||
if (isDryRun) {
|
||||
throw new DryRunException(output);
|
||||
}
|
||||
if (flowClass.equals(LoginFlow.class)) {
|
||||
// In LoginFlow, registrarId isn't known until after the flow executes, so save
|
||||
// it then.
|
||||
stopwatch.tick("Login flow started setting registrar id.");
|
||||
eppMetricBuilder.setRegistrarId(sessionMetadata.getRegistrarId());
|
||||
stopwatch.tick("Login flow finished setting registrar id.");
|
||||
}
|
||||
return output;
|
||||
} catch (EppException e) {
|
||||
|
||||
@@ -21,6 +21,7 @@ import static google.registry.xml.ValidationMode.STRICT;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import google.registry.flows.EppException.CommandUseErrorException;
|
||||
import google.registry.flows.EppException.ParameterValueRangeErrorException;
|
||||
@@ -30,6 +31,7 @@ import google.registry.flows.custom.EntityChanges;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.adapters.CurrencyUnitAdapter.UnknownCurrencyException;
|
||||
import google.registry.model.eppcommon.EppXmlTransformer;
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
import google.registry.model.eppinput.EppInput.WrongProtocolVersionException;
|
||||
import google.registry.model.eppoutput.EppOutput;
|
||||
import google.registry.model.host.InetAddressAdapter.IpVersionMismatchException;
|
||||
@@ -40,6 +42,9 @@ import java.util.List;
|
||||
/** Static utility functions for flows. */
|
||||
public final class FlowUtils {
|
||||
|
||||
public static final ImmutableSet<StatusValue> DELETE_PROHIBITED_STATUSES =
|
||||
ImmutableSet.of(StatusValue.CLIENT_DELETE_PROHIBITED, StatusValue.SERVER_DELETE_PROHIBITED);
|
||||
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
|
||||
private FlowUtils() {}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
package google.registry.flows.contact;
|
||||
|
||||
import static google.registry.flows.FlowUtils.DELETE_PROHIBITED_STATUSES;
|
||||
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
|
||||
import static google.registry.flows.ResourceFlowUtils.checkLinkedDomains;
|
||||
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
|
||||
@@ -65,12 +66,6 @@ import org.joda.time.DateTime;
|
||||
@ReportingSpec(ActivityReportField.CONTACT_DELETE)
|
||||
public final class ContactDeleteFlow implements MutatingFlow {
|
||||
|
||||
private static final ImmutableSet<StatusValue> DISALLOWED_STATUSES =
|
||||
ImmutableSet.of(
|
||||
StatusValue.CLIENT_DELETE_PROHIBITED,
|
||||
StatusValue.PENDING_DELETE,
|
||||
StatusValue.SERVER_DELETE_PROHIBITED);
|
||||
|
||||
@Inject ExtensionManager extensionManager;
|
||||
@Inject @RegistrarId String registrarId;
|
||||
@Inject @TargetId String targetId;
|
||||
@@ -91,9 +86,10 @@ public final class ContactDeleteFlow implements MutatingFlow {
|
||||
DateTime now = tm().getTransactionTime();
|
||||
checkLinkedDomains(targetId, now, Contact.class);
|
||||
Contact existingContact = loadAndVerifyExistence(Contact.class, targetId, now);
|
||||
verifyNoDisallowedStatuses(existingContact, DISALLOWED_STATUSES);
|
||||
verifyOptionalAuthInfo(authInfo, existingContact);
|
||||
verifyNoDisallowedStatuses(existingContact, ImmutableSet.of(StatusValue.PENDING_DELETE));
|
||||
if (!isSuperuser) {
|
||||
verifyNoDisallowedStatuses(existingContact, DELETE_PROHIBITED_STATUSES);
|
||||
verifyResourceOwnership(registrarId, existingContact);
|
||||
}
|
||||
// Handle pending transfers on contact deletion.
|
||||
|
||||
@@ -17,6 +17,7 @@ package google.registry.flows.domain;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
import static google.registry.dns.DnsUtils.requestDomainDnsRefresh;
|
||||
import static google.registry.flows.FlowUtils.DELETE_PROHIBITED_STATUSES;
|
||||
import static google.registry.flows.FlowUtils.createHistoryEntryId;
|
||||
import static google.registry.flows.FlowUtils.persistEntityChanges;
|
||||
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
|
||||
@@ -122,11 +123,6 @@ public final class DomainDeleteFlow implements MutatingFlow, SqlStatementLogging
|
||||
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
|
||||
private static final ImmutableSet<StatusValue> DISALLOWED_STATUSES = ImmutableSet.of(
|
||||
StatusValue.CLIENT_DELETE_PROHIBITED,
|
||||
StatusValue.PENDING_DELETE,
|
||||
StatusValue.SERVER_DELETE_PROHIBITED);
|
||||
|
||||
@Inject ExtensionManager extensionManager;
|
||||
@Inject EppInput eppInput;
|
||||
@Inject SessionMetadata sessionMetadata;
|
||||
@@ -304,9 +300,10 @@ public final class DomainDeleteFlow implements MutatingFlow, SqlStatementLogging
|
||||
|
||||
private void verifyDeleteAllowed(Domain existingDomain, Tld tld, DateTime now)
|
||||
throws EppException {
|
||||
verifyNoDisallowedStatuses(existingDomain, DISALLOWED_STATUSES);
|
||||
verifyOptionalAuthInfo(authInfo, existingDomain);
|
||||
verifyNoDisallowedStatuses(existingDomain, ImmutableSet.of(StatusValue.PENDING_DELETE));
|
||||
if (!isSuperuser) {
|
||||
verifyNoDisallowedStatuses(existingDomain, DELETE_PROHIBITED_STATUSES);
|
||||
verifyResourceOwnership(registrarId, existingDomain);
|
||||
verifyNotInPredelegation(tld, now);
|
||||
checkAllowedAccessToTld(registrarId, tld.getTld().toString());
|
||||
|
||||
@@ -481,10 +481,10 @@ public class DomainFlowUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforces the presence/absence of contact data depending on the minimum data set migration
|
||||
* schedule.
|
||||
* Enforces the presence/absence of contact data on domain creates depending on the minimum data
|
||||
* set migration schedule.
|
||||
*/
|
||||
static void validateContactDataPresence(
|
||||
static void validateCreateContactData(
|
||||
Optional<VKey<Contact>> registrant, Set<DesignatedContact> contacts)
|
||||
throws RequiredParameterMissingException, ParameterValuePolicyErrorException {
|
||||
// TODO(b/353347632): Change these flag checks to a registry config check once minimum data set
|
||||
@@ -514,6 +514,45 @@ public class DomainFlowUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforces the presence/absence of contact data on domain updates depending on the minimum data
|
||||
* set migration schedule.
|
||||
*/
|
||||
static void validateUpdateContactData(
|
||||
Optional<VKey<Contact>> existingRegistrant,
|
||||
Optional<VKey<Contact>> newRegistrant,
|
||||
Set<DesignatedContact> existingContacts,
|
||||
Set<DesignatedContact> newContacts)
|
||||
throws RequiredParameterMissingException, ParameterValuePolicyErrorException {
|
||||
// TODO(b/353347632): Change these flag checks to a registry config check once minimum data set
|
||||
// migration is completed.
|
||||
if (FeatureFlag.isActiveNow(MINIMUM_DATASET_CONTACTS_PROHIBITED)) {
|
||||
// Throw if the update specifies a new registrant that is different from the existing one.
|
||||
if (newRegistrant.isPresent() && !newRegistrant.equals(existingRegistrant)) {
|
||||
throw new RegistrantProhibitedException();
|
||||
}
|
||||
// Throw if the update specifies any new contacts that weren't already present on the domain.
|
||||
if (!Sets.difference(newContacts, existingContacts).isEmpty()) {
|
||||
throw new ContactsProhibitedException();
|
||||
}
|
||||
} else if (!FeatureFlag.isActiveNow(MINIMUM_DATASET_CONTACTS_OPTIONAL)) {
|
||||
// Throw if the update empties out a registrant that had been present.
|
||||
if (newRegistrant.isEmpty() && existingRegistrant.isPresent()) {
|
||||
throw new MissingRegistrantException();
|
||||
}
|
||||
// Throw if the update contains no admin contact when one had been present.
|
||||
if (existingContacts.stream().anyMatch(c -> c.getType().equals(Type.ADMIN))
|
||||
&& newContacts.stream().noneMatch(c -> c.getType().equals(Type.ADMIN))) {
|
||||
throw new MissingAdminContactException();
|
||||
}
|
||||
// Throw if the update contains no tech contact when one had been present.
|
||||
if (existingContacts.stream().anyMatch(c -> c.getType().equals(Type.TECH))
|
||||
&& newContacts.stream().noneMatch(c -> c.getType().equals(Type.TECH))) {
|
||||
throw new MissingTechnicalContactException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void validateRegistrantAllowedOnTld(String tld, Optional<String> registrantContactId)
|
||||
throws RegistrantNotAllowedException {
|
||||
ImmutableSet<String> allowedRegistrants = Tld.get(tld).getAllowedRegistrantContactIds();
|
||||
@@ -1054,7 +1093,7 @@ public class DomainFlowUtils {
|
||||
String tldStr = tld.getTldStr();
|
||||
validateRegistrantAllowedOnTld(tldStr, command.getRegistrantContactId());
|
||||
validateNoDuplicateContacts(command.getContacts());
|
||||
validateContactDataPresence(command.getRegistrant(), command.getContacts());
|
||||
validateCreateContactData(command.getRegistrant(), command.getContacts());
|
||||
ImmutableSet<String> hostNames = command.getNameserverHostNames();
|
||||
validateNameserversCountForTld(tldStr, domainName, hostNames.size());
|
||||
validateNameserversAllowedOnTld(tldStr, hostNames);
|
||||
@@ -1358,7 +1397,7 @@ public class DomainFlowUtils {
|
||||
}
|
||||
|
||||
/** Domain name is under tld which doesn't exist. */
|
||||
static class TldDoesNotExistException extends ParameterValueRangeErrorException {
|
||||
public static class TldDoesNotExistException extends ParameterValueRangeErrorException {
|
||||
public TldDoesNotExistException(String tld) {
|
||||
super(String.format("Domain name is under tld %s which doesn't exist", tld));
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ import static google.registry.flows.ResourceFlowUtils.verifyResourceOwnership;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.cloneAndLinkReferences;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.updateDsData;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateContactDataPresence;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateContactsHaveTypes;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateDsData;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateFeesAckedIfPresent;
|
||||
@@ -38,6 +37,7 @@ import static google.registry.flows.domain.DomainFlowUtils.validateNameserversAl
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateNameserversCountForTld;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateNoDuplicateContacts;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateRegistrantAllowedOnTld;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.validateUpdateContactData;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.verifyClientUpdateNotProhibited;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.verifyNotInPendingDelete;
|
||||
import static google.registry.model.common.FeatureFlag.FeatureName.MINIMUM_DATASET_CONTACTS_OPTIONAL;
|
||||
@@ -186,7 +186,7 @@ public final class DomainUpdateFlow implements MutatingFlow {
|
||||
Domain newDomain = performUpdate(command, existingDomain, now);
|
||||
DomainHistory domainHistory =
|
||||
historyBuilder.setType(DOMAIN_UPDATE).setDomain(newDomain).build();
|
||||
validateNewState(newDomain);
|
||||
validateNewState(existingDomain, newDomain);
|
||||
if (requiresDnsUpdate(existingDomain, newDomain)) {
|
||||
requestDomainDnsRefresh(targetId);
|
||||
}
|
||||
@@ -328,8 +328,13 @@ public final class DomainUpdateFlow implements MutatingFlow {
|
||||
* compliant with the additions or amendments, otherwise existing data can become invalid and
|
||||
* cause Domain update failure.
|
||||
*/
|
||||
private static void validateNewState(Domain newDomain) throws EppException {
|
||||
validateContactDataPresence(newDomain.getRegistrant(), newDomain.getContacts());
|
||||
private static void validateNewState(Domain existingDomain, Domain newDomain)
|
||||
throws EppException {
|
||||
validateUpdateContactData(
|
||||
existingDomain.getRegistrant(),
|
||||
newDomain.getRegistrant(),
|
||||
existingDomain.getContacts(),
|
||||
newDomain.getContacts());
|
||||
validateDsData(newDomain.getDsData());
|
||||
validateNameserversCountForTld(
|
||||
newDomain.getTld(),
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package google.registry.flows.host;
|
||||
|
||||
import static google.registry.dns.DnsUtils.requestHostDnsRefresh;
|
||||
import static google.registry.flows.FlowUtils.DELETE_PROHIBITED_STATUSES;
|
||||
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
|
||||
import static google.registry.flows.ResourceFlowUtils.checkLinkedDomains;
|
||||
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
|
||||
@@ -65,12 +66,6 @@ import org.joda.time.DateTime;
|
||||
@ReportingSpec(ActivityReportField.HOST_DELETE)
|
||||
public final class HostDeleteFlow implements MutatingFlow {
|
||||
|
||||
private static final ImmutableSet<StatusValue> DISALLOWED_STATUSES =
|
||||
ImmutableSet.of(
|
||||
StatusValue.CLIENT_DELETE_PROHIBITED,
|
||||
StatusValue.PENDING_DELETE,
|
||||
StatusValue.SERVER_DELETE_PROHIBITED);
|
||||
|
||||
@Inject ExtensionManager extensionManager;
|
||||
@Inject @RegistrarId String registrarId;
|
||||
@Inject @TargetId String targetId;
|
||||
@@ -91,8 +86,9 @@ public final class HostDeleteFlow implements MutatingFlow {
|
||||
validateHostName(targetId);
|
||||
checkLinkedDomains(targetId, now, Host.class);
|
||||
Host existingHost = loadAndVerifyExistence(Host.class, targetId, now);
|
||||
verifyNoDisallowedStatuses(existingHost, DISALLOWED_STATUSES);
|
||||
verifyNoDisallowedStatuses(existingHost, ImmutableSet.of(StatusValue.PENDING_DELETE));
|
||||
if (!isSuperuser) {
|
||||
verifyNoDisallowedStatuses(existingHost, DELETE_PROHIBITED_STATUSES);
|
||||
// Hosts transfer with their superordinate domains, so for hosts with a superordinate domain,
|
||||
// the client id, needs to be read off of it.
|
||||
EppResource owningResource =
|
||||
|
||||
@@ -47,6 +47,7 @@ import google.registry.model.eppinput.EppInput.Options;
|
||||
import google.registry.model.eppinput.EppInput.Services;
|
||||
import google.registry.model.eppoutput.EppResponse;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.util.StopwatchLogger;
|
||||
import jakarta.inject.Inject;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
@@ -97,19 +98,25 @@ public class LoginFlow implements MutatingFlow {
|
||||
|
||||
/** Run the flow without bothering to log errors. The {@link #run} method will do that for us. */
|
||||
private EppResponse runWithoutLogging() throws EppException {
|
||||
final StopwatchLogger stopwatch = new StopwatchLogger();
|
||||
extensionManager.validate(); // There are no legal extensions for this flow.
|
||||
stopwatch.tick("LoginFlow extension validate");
|
||||
Login login = (Login) eppInput.getCommandWrapper().getCommand();
|
||||
stopwatch.tick("LoginFlow getCommand");
|
||||
if (!registrarId.isEmpty()) {
|
||||
throw new AlreadyLoggedInException();
|
||||
}
|
||||
Options options = login.getOptions();
|
||||
stopwatch.tick("LoginFlow getOptions");
|
||||
if (!ProtocolDefinition.LANGUAGE.equals(options.getLanguage())) {
|
||||
throw new UnsupportedLanguageException();
|
||||
}
|
||||
Services services = login.getServices();
|
||||
stopwatch.tick("LoginFlow getServices");
|
||||
Set<String> unsupportedObjectServices = difference(
|
||||
nullToEmpty(services.getObjectServices()),
|
||||
ProtocolDefinition.SUPPORTED_OBJECT_SERVICES);
|
||||
stopwatch.tick("LoginFlow difference unsupportedObjectServices");
|
||||
if (!unsupportedObjectServices.isEmpty()) {
|
||||
throw new UnimplementedObjectServiceException();
|
||||
}
|
||||
@@ -121,11 +128,12 @@ public class LoginFlow implements MutatingFlow {
|
||||
}
|
||||
serviceExtensionUrisBuilder.add(uri);
|
||||
}
|
||||
stopwatch.tick("LoginFlow serviceExtensionUrisBuilder");
|
||||
Optional<Registrar> registrar = Registrar.loadByRegistrarIdCached(login.getClientId());
|
||||
if (registrar.isEmpty()) {
|
||||
throw new BadRegistrarIdException(login.getClientId());
|
||||
}
|
||||
|
||||
stopwatch.tick("LoginFlow loadByRegistrarIdCached");
|
||||
// AuthenticationErrorExceptions will propagate up through here.
|
||||
try {
|
||||
credentials.validate(registrar.get(), login.getPassword());
|
||||
@@ -137,6 +145,7 @@ public class LoginFlow implements MutatingFlow {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
stopwatch.tick("LoginFlow credentials.validate");
|
||||
if (!registrar.get().isLive()) {
|
||||
throw new RegistrarAccountNotActiveException();
|
||||
}
|
||||
@@ -145,17 +154,24 @@ public class LoginFlow implements MutatingFlow {
|
||||
String newPassword = login.getNewPassword().get();
|
||||
// Load fresh from database (bypassing the cache) to ensure we don't save stale data.
|
||||
Optional<Registrar> freshRegistrar = Registrar.loadByRegistrarId(login.getClientId());
|
||||
stopwatch.tick("LoginFlow reload freshRegistrar");
|
||||
if (freshRegistrar.isEmpty()) {
|
||||
throw new BadRegistrarIdException(login.getClientId());
|
||||
}
|
||||
tm().put(freshRegistrar.get().asBuilder().setPassword(newPassword).build());
|
||||
stopwatch.tick("LoginFlow updated password");
|
||||
}
|
||||
|
||||
// We are in!
|
||||
sessionMetadata.resetFailedLoginAttempts();
|
||||
stopwatch.tick("LoginFlow resetFailedLoginAttempts");
|
||||
sessionMetadata.setRegistrarId(login.getClientId());
|
||||
stopwatch.tick("LoginFlow setRegistrarId");
|
||||
sessionMetadata.setServiceExtensionUris(serviceExtensionUrisBuilder.build());
|
||||
return responseBuilder.setIsLoginResponse().build();
|
||||
stopwatch.tick("LoginFlow setServiceExtensionUris");
|
||||
EppResponse eppResponse = responseBuilder.setIsLoginResponse().build();
|
||||
stopwatch.tick("LoginFlow eppResponse build()");
|
||||
return eppResponse;
|
||||
}
|
||||
|
||||
/** Registrar with this ID could not be found. */
|
||||
|
||||
@@ -17,10 +17,7 @@ package google.registry.loadtest;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static com.google.common.collect.Lists.partition;
|
||||
import static google.registry.security.XsrfTokenManager.X_CSRF_TOKEN;
|
||||
import static google.registry.util.ResourceUtils.readResourceUtf8;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.joda.time.DateTimeZone.UTC;
|
||||
|
||||
import com.google.cloud.tasks.v2.Task;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
@@ -34,7 +31,7 @@ import google.registry.request.Action;
|
||||
import google.registry.request.Action.GaeService;
|
||||
import google.registry.request.Parameter;
|
||||
import google.registry.request.auth.Auth;
|
||||
import google.registry.security.XsrfTokenManager;
|
||||
import google.registry.util.Clock;
|
||||
import google.registry.util.RegistryEnvironment;
|
||||
import jakarta.inject.Inject;
|
||||
import java.time.Instant;
|
||||
@@ -67,11 +64,9 @@ public class LoadTestAction implements Runnable {
|
||||
private static final int NUM_QUEUES = 10;
|
||||
private static final int MAX_TASKS_PER_LOAD = 100;
|
||||
private static final int ARBITRARY_VALID_HOST_LENGTH = 40;
|
||||
private static final int MAX_CONTACT_LENGTH = 13;
|
||||
private static final int MAX_DOMAIN_LABEL_LENGTH = 63;
|
||||
|
||||
private static final String EXISTING_DOMAIN = "testdomain";
|
||||
private static final String EXISTING_CONTACT = "contact";
|
||||
private static final String EXISTING_HOST = "ns1";
|
||||
|
||||
private static final Random random = new Random();
|
||||
@@ -85,8 +80,8 @@ public class LoadTestAction implements Runnable {
|
||||
|
||||
/**
|
||||
* The number of seconds to delay the execution of the first load testing tasks by. Preparatory
|
||||
* work of creating independent contacts and hosts that will be used for later domain creation
|
||||
* testing occurs during this period, so make sure that it is long enough.
|
||||
* work of creating independent hosts that will be used for later domain creation testing occurs
|
||||
* during this period, so make sure that it is long enough.
|
||||
*/
|
||||
@Inject
|
||||
@Parameter("delaySeconds")
|
||||
@@ -120,21 +115,6 @@ public class LoadTestAction implements Runnable {
|
||||
@Parameter("domainChecks")
|
||||
int domainChecksPerSecond;
|
||||
|
||||
/** The number of successful contact creates to enqueue per second over the length of the test. */
|
||||
@Inject
|
||||
@Parameter("successfulContactCreates")
|
||||
int successfulContactCreatesPerSecond;
|
||||
|
||||
/** The number of failed contact creates to enqueue per second over the length of the test. */
|
||||
@Inject
|
||||
@Parameter("failedContactCreates")
|
||||
int failedContactCreatesPerSecond;
|
||||
|
||||
/** The number of successful contact infos to enqueue per second over the length of the test. */
|
||||
@Inject
|
||||
@Parameter("contactInfos")
|
||||
int contactInfosPerSecond;
|
||||
|
||||
/** The number of successful host creates to enqueue per second over the length of the test. */
|
||||
@Inject
|
||||
@Parameter("successfulHostCreates")
|
||||
@@ -152,9 +132,8 @@ public class LoadTestAction implements Runnable {
|
||||
|
||||
@Inject CloudTasksUtils cloudTasksUtils;
|
||||
|
||||
private final String xmlContactCreateTmpl;
|
||||
private final String xmlContactCreateFail;
|
||||
private final String xmlContactInfo;
|
||||
@Inject Clock clock;
|
||||
|
||||
private final String xmlDomainCheck;
|
||||
private final String xmlDomainCreateTmpl;
|
||||
private final String xmlDomainCreateFail;
|
||||
@@ -163,53 +142,35 @@ public class LoadTestAction implements Runnable {
|
||||
private final String xmlHostCreateFail;
|
||||
private final String xmlHostInfo;
|
||||
|
||||
/**
|
||||
* The XSRF token to be used for making requests to the epptool endpoint.
|
||||
*
|
||||
* <p>Note that the email address is set to empty, because the logged-in user hitting this
|
||||
* endpoint will not be the same as when the tasks themselves fire and hit the epptool endpoint.
|
||||
*/
|
||||
private final String xsrfToken;
|
||||
|
||||
@Inject
|
||||
LoadTestAction(@Parameter("tld") String tld, XsrfTokenManager xsrfTokenManager) {
|
||||
xmlContactCreateTmpl = loadXml("contact_create");
|
||||
xmlContactCreateFail = xmlContactCreateTmpl.replace("%contact%", EXISTING_CONTACT);
|
||||
xmlContactInfo = loadXml("contact_info").replace("%contact%", EXISTING_CONTACT);
|
||||
LoadTestAction(@Parameter("tld") String tld) {
|
||||
xmlDomainCheck =
|
||||
loadXml("domain_check").replace("%tld%", tld).replace("%domain%", EXISTING_DOMAIN);
|
||||
xmlDomainCreateTmpl = loadXml("domain_create").replace("%tld%", tld);
|
||||
xmlDomainCreateFail =
|
||||
xmlDomainCreateTmpl
|
||||
.replace("%domain%", EXISTING_DOMAIN)
|
||||
.replace("%contact%", EXISTING_CONTACT)
|
||||
.replace("%host%", EXISTING_HOST);
|
||||
xmlDomainInfo =
|
||||
loadXml("domain_info").replace("%tld%", tld).replace("%domain%", EXISTING_DOMAIN);
|
||||
xmlHostCreateTmpl = loadXml("host_create");
|
||||
xmlHostCreateFail = xmlHostCreateTmpl.replace("%host%", EXISTING_HOST);
|
||||
xmlHostInfo = loadXml("host_info").replace("%host%", EXISTING_HOST);
|
||||
xsrfToken = xsrfTokenManager.generateToken("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
validateAndLogRequest();
|
||||
DateTime initialStartSecond = DateTime.now(UTC).plusSeconds(delaySeconds);
|
||||
DateTime initialStartSecond = clock.nowUtc().plusSeconds(delaySeconds);
|
||||
ImmutableList.Builder<String> preTaskXmls = new ImmutableList.Builder<>();
|
||||
ImmutableList.Builder<String> contactNamesBuilder = new ImmutableList.Builder<>();
|
||||
ImmutableList.Builder<String> hostPrefixesBuilder = new ImmutableList.Builder<>();
|
||||
for (int i = 0; i < successfulDomainCreatesPerSecond; i++) {
|
||||
String contactName = getRandomLabel(MAX_CONTACT_LENGTH);
|
||||
String hostPrefix = getRandomLabel(ARBITRARY_VALID_HOST_LENGTH);
|
||||
contactNamesBuilder.add(contactName);
|
||||
hostPrefixesBuilder.add(hostPrefix);
|
||||
preTaskXmls.add(
|
||||
xmlContactCreateTmpl.replace("%contact%", contactName),
|
||||
xmlHostCreateTmpl.replace("%host%", hostPrefix));
|
||||
}
|
||||
enqueue(createTasks(preTaskXmls.build(), DateTime.now(UTC)));
|
||||
ImmutableList<String> contactNames = contactNamesBuilder.build();
|
||||
enqueue(createTasks(preTaskXmls.build(), clock.nowUtc()));
|
||||
ImmutableList<String> hostPrefixes = hostPrefixesBuilder.build();
|
||||
|
||||
ImmutableList.Builder<Task> tasks = new ImmutableList.Builder<>();
|
||||
@@ -217,30 +178,17 @@ public class LoadTestAction implements Runnable {
|
||||
DateTime startSecond = initialStartSecond.plusSeconds(offsetSeconds);
|
||||
// The first "failed" creates might actually succeed if the object doesn't already exist, but
|
||||
// that shouldn't affect the load numbers.
|
||||
tasks.addAll(
|
||||
createTasks(
|
||||
createNumCopies(xmlContactCreateFail, failedContactCreatesPerSecond), startSecond));
|
||||
tasks.addAll(
|
||||
createTasks(createNumCopies(xmlHostCreateFail, failedHostCreatesPerSecond), startSecond));
|
||||
tasks.addAll(
|
||||
createTasks(
|
||||
createNumCopies(xmlDomainCreateFail, failedDomainCreatesPerSecond), startSecond));
|
||||
// We can do infos on the known existing objects.
|
||||
tasks.addAll(
|
||||
createTasks(createNumCopies(xmlContactInfo, contactInfosPerSecond), startSecond));
|
||||
tasks.addAll(createTasks(createNumCopies(xmlHostInfo, hostInfosPerSecond), startSecond));
|
||||
tasks.addAll(createTasks(createNumCopies(xmlDomainInfo, domainInfosPerSecond), startSecond));
|
||||
// The domain check template uses "example.TLD" which won't exist, and one existing domain.
|
||||
tasks.addAll(
|
||||
createTasks(createNumCopies(xmlDomainCheck, domainChecksPerSecond), startSecond));
|
||||
// Do successful creates on random names
|
||||
tasks.addAll(
|
||||
createTasks(
|
||||
createNumCopies(xmlContactCreateTmpl, successfulContactCreatesPerSecond)
|
||||
.stream()
|
||||
.map(randomNameReplacer("%contact%", MAX_CONTACT_LENGTH))
|
||||
.collect(toImmutableList()),
|
||||
startSecond));
|
||||
tasks.addAll(
|
||||
createTasks(
|
||||
createNumCopies(xmlHostCreateTmpl, successfulHostCreatesPerSecond)
|
||||
@@ -253,7 +201,6 @@ public class LoadTestAction implements Runnable {
|
||||
createNumCopies(xmlDomainCreateTmpl, successfulDomainCreatesPerSecond)
|
||||
.stream()
|
||||
.map(randomNameReplacer("%domain%", MAX_DOMAIN_LABEL_LENGTH))
|
||||
.map(listNameReplacer("%contact%", contactNames))
|
||||
.map(listNameReplacer("%host%", hostPrefixes))
|
||||
.collect(toImmutableList()),
|
||||
startSecond));
|
||||
@@ -272,9 +219,6 @@ public class LoadTestAction implements Runnable {
|
||||
|| failedDomainCreatesPerSecond > 0
|
||||
|| domainInfosPerSecond > 0
|
||||
|| domainChecksPerSecond > 0
|
||||
|| successfulContactCreatesPerSecond > 0
|
||||
|| failedContactCreatesPerSecond > 0
|
||||
|| contactInfosPerSecond > 0
|
||||
|| successfulHostCreatesPerSecond > 0
|
||||
|| failedHostCreatesPerSecond > 0
|
||||
|| hostInfosPerSecond > 0,
|
||||
@@ -282,8 +226,7 @@ public class LoadTestAction implements Runnable {
|
||||
logger.atInfo().log(
|
||||
"Running load test with the following params. registrarId: %s, delaySeconds: %d, "
|
||||
+ "runSeconds: %d, successful|failed domain creates/s: %d|%d, domain infos/s: %d, "
|
||||
+ "domain checks/s: %d, successful|failed contact creates/s: %d|%d, "
|
||||
+ "contact infos/s: %d, successful|failed host creates/s: %d|%d, host infos/s: %d.",
|
||||
+ "domain checks/s: %d, successful|failed host creates/s: %d|%d, host infos/s: %d.",
|
||||
registrarId,
|
||||
delaySeconds,
|
||||
runSeconds,
|
||||
@@ -291,9 +234,6 @@ public class LoadTestAction implements Runnable {
|
||||
failedDomainCreatesPerSecond,
|
||||
domainInfosPerSecond,
|
||||
domainChecksPerSecond,
|
||||
successfulContactCreatesPerSecond,
|
||||
failedContactCreatesPerSecond,
|
||||
contactInfosPerSecond,
|
||||
successfulHostCreatesPerSecond,
|
||||
failedHostCreatesPerSecond,
|
||||
hostInfosPerSecond);
|
||||
@@ -303,10 +243,10 @@ public class LoadTestAction implements Runnable {
|
||||
return readResourceUtf8(LoadTestAction.class, String.format("templates/%s.xml", name));
|
||||
}
|
||||
|
||||
private List<String> createNumCopies(String xml, int numCopies) {
|
||||
private ImmutableList<String> createNumCopies(String xml, int numCopies) {
|
||||
String[] xmls = new String[numCopies];
|
||||
Arrays.fill(xmls, xml);
|
||||
return asList(xmls);
|
||||
return ImmutableList.copyOf(xmls);
|
||||
}
|
||||
|
||||
private Function<String, String> listNameReplacer(final String toReplace, List<String> choices) {
|
||||
@@ -326,35 +266,27 @@ public class LoadTestAction implements Runnable {
|
||||
return name.toString();
|
||||
}
|
||||
|
||||
private List<Task> createTasks(List<String> xmls, DateTime start) {
|
||||
private ImmutableList<Task> createTasks(ImmutableList<String> xmls, DateTime start) {
|
||||
ImmutableList.Builder<Task> tasks = new ImmutableList.Builder<>();
|
||||
for (int i = 0; i < xmls.size(); i++) {
|
||||
// Space tasks evenly within across a second.
|
||||
Instant scheduleTime =
|
||||
Instant.ofEpochMilli(start.plusMillis((int) (1000.0 / xmls.size() * i)).getMillis());
|
||||
tasks.add(
|
||||
Task.newBuilder()
|
||||
.setAppEngineHttpRequest(
|
||||
cloudTasksUtils
|
||||
.createTask(
|
||||
EppToolAction.class,
|
||||
Action.Method.POST,
|
||||
ImmutableMultimap.of(
|
||||
"clientId",
|
||||
registrarId,
|
||||
"superuser",
|
||||
Boolean.FALSE.toString(),
|
||||
"dryRun",
|
||||
Boolean.FALSE.toString(),
|
||||
"xml",
|
||||
xmls.get(i)))
|
||||
.toBuilder()
|
||||
.getAppEngineHttpRequest()
|
||||
.toBuilder()
|
||||
// TODO: investigate if the following is necessary now that
|
||||
// LegacyAuthenticationMechanism is gone.
|
||||
.putHeaders(X_CSRF_TOKEN, xsrfToken)
|
||||
.build())
|
||||
cloudTasksUtils
|
||||
.createTask(
|
||||
EppToolAction.class,
|
||||
Action.Method.POST,
|
||||
ImmutableMultimap.of(
|
||||
"clientId",
|
||||
registrarId,
|
||||
"superuser",
|
||||
Boolean.FALSE.toString(),
|
||||
"dryRun",
|
||||
Boolean.FALSE.toString(),
|
||||
"xml",
|
||||
xmls.get(i)))
|
||||
.toBuilder()
|
||||
.setScheduleTime(
|
||||
Timestamp.newBuilder()
|
||||
.setSeconds(scheduleTime.getEpochSecond())
|
||||
@@ -365,7 +297,7 @@ public class LoadTestAction implements Runnable {
|
||||
return tasks.build();
|
||||
}
|
||||
|
||||
private void enqueue(List<Task> tasks) {
|
||||
private void enqueue(ImmutableList<Task> tasks) {
|
||||
List<List<Task>> chunks = partition(tasks, MAX_TASKS_PER_LOAD);
|
||||
// Farm out tasks to multiple queues to work around queue qps quotas.
|
||||
for (int i = 0; i < chunks.size(); i++) {
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<create>
|
||||
<contact:create
|
||||
xmlns:contact="urn:ietf:params:xml:ns:contact-1.0">
|
||||
<contact:id>%contact%</contact:id>
|
||||
<contact:postalInfo type="int">
|
||||
<contact:name>John Doe</contact:name>
|
||||
<contact:org>Example Inc.</contact:org>
|
||||
<contact:addr>
|
||||
<contact:street>123 Example Dr.</contact:street>
|
||||
<contact:street>Suite 100</contact:street>
|
||||
<contact:city>Dulles</contact:city>
|
||||
<contact:sp>VA</contact:sp>
|
||||
<contact:pc>20166-6503</contact:pc>
|
||||
<contact:cc>US</contact:cc>
|
||||
</contact:addr>
|
||||
</contact:postalInfo>
|
||||
<contact:voice x="1234">+1.7035555555</contact:voice>
|
||||
<contact:fax>+1.7035555556</contact:fax>
|
||||
<contact:email>jdoe@example.com</contact:email>
|
||||
<contact:authInfo>
|
||||
<contact:pw>2fooBAR</contact:pw>
|
||||
</contact:authInfo>
|
||||
<contact:disclose flag="1">
|
||||
<contact:voice/>
|
||||
<contact:email/>
|
||||
</contact:disclose>
|
||||
</contact:create>
|
||||
</create>
|
||||
<clTRID>trid</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
@@ -1,14 +0,0 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<info>
|
||||
<contact:info
|
||||
xmlns:contact="urn:ietf:params:xml:ns:contact-1.0">
|
||||
<contact:id>%contact%</contact:id>
|
||||
<contact:authInfo>
|
||||
<contact:pw>2fooBAR</contact:pw>
|
||||
</contact:authInfo>
|
||||
</contact:info>
|
||||
</info>
|
||||
<clTRID>trid</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
@@ -8,9 +8,6 @@
|
||||
<domain:ns>
|
||||
<domain:hostObj>%host%.example.com</domain:hostObj>
|
||||
</domain:ns>
|
||||
<domain:registrant>%contact%</domain:registrant>
|
||||
<domain:contact type="admin">%contact%</domain:contact>
|
||||
<domain:contact type="tech">%contact%</domain:contact>
|
||||
<domain:authInfo>
|
||||
<domain:pw>2fooBAR</domain:pw>
|
||||
</domain:authInfo>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<host:create
|
||||
xmlns:host="urn:ietf:params:xml:ns:host-1.0">
|
||||
<host:name>%host%.example.com</host:name>
|
||||
<host:addr ip="v4">8.8.8.8</host:addr>
|
||||
</host:create>
|
||||
</create>
|
||||
<clTRID>trid</clTRID>
|
||||
|
||||
@@ -578,7 +578,7 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
|
||||
* address.
|
||||
*/
|
||||
public ImmutableSortedSet<RegistrarPoc> getContacts() {
|
||||
return getContactPocs(tm()).stream()
|
||||
return getPocs(tm()).stream()
|
||||
.filter(Objects::nonNull)
|
||||
.collect(toImmutableSortedSet(CONTACT_EMAIL_COMPARATOR));
|
||||
}
|
||||
@@ -590,8 +590,8 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
|
||||
* <p>This method queries the replica database. It is reserved for use cases that can tolerate
|
||||
* slightly stale data.
|
||||
*/
|
||||
public ImmutableSortedSet<RegistrarPoc> getContactsFromReplica() {
|
||||
return getContactPocs(replicaTm()).stream()
|
||||
public ImmutableSortedSet<RegistrarPoc> getPocsFromReplica() {
|
||||
return getPocs(replicaTm()).stream()
|
||||
.filter(Objects::nonNull)
|
||||
.collect(toImmutableSortedSet(CONTACT_EMAIL_COMPARATOR));
|
||||
}
|
||||
@@ -600,8 +600,8 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
|
||||
* Returns a list of {@link RegistrarPoc} objects of a given type for this registrar sorted by
|
||||
* their email address.
|
||||
*/
|
||||
public ImmutableSortedSet<RegistrarPoc> getContactsOfType(final RegistrarPoc.Type type) {
|
||||
return getContactPocs(tm()).stream()
|
||||
public ImmutableSortedSet<RegistrarPoc> getPocsOfType(final RegistrarPoc.Type type) {
|
||||
return getPocs(tm()).stream()
|
||||
.filter(Objects::nonNull)
|
||||
.filter((@Nullable RegistrarPoc contact) -> contact.getTypes().contains(type))
|
||||
.collect(toImmutableSortedSet(CONTACT_EMAIL_COMPARATOR));
|
||||
@@ -615,7 +615,7 @@ public class Registrar extends UpdateAutoTimestampEntity implements Buildable, J
|
||||
return getContacts().stream().filter(RegistrarPoc::getVisibleInDomainWhoisAsAbuse).findFirst();
|
||||
}
|
||||
|
||||
private ImmutableList<RegistrarPoc> getContactPocs(TransactionManager txnManager) {
|
||||
private ImmutableList<RegistrarPoc> getPocs(TransactionManager txnManager) {
|
||||
return txnManager.transact(() -> RegistrarPoc.loadForRegistrar(registrarId));
|
||||
}
|
||||
|
||||
|
||||
@@ -95,10 +95,4 @@ public class SignedMarkRevocationList extends ImmutableObject {
|
||||
public int size() {
|
||||
return revokes.size();
|
||||
}
|
||||
|
||||
/** Save this list to Cloud SQL. Returns {@code this}. */
|
||||
public SignedMarkRevocationList save() {
|
||||
SignedMarkRevocationListDao.save(this);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,11 +44,25 @@ public class SignedMarkRevocationListDao {
|
||||
return smdrl.orElseGet(() -> SignedMarkRevocationList.create(START_OF_TIME, ImmutableMap.of()));
|
||||
}
|
||||
|
||||
/** Save the given {@link SignedMarkRevocationList} */
|
||||
static void save(SignedMarkRevocationList signedMarkRevocationList) {
|
||||
tm().transact(() -> tm().insert(signedMarkRevocationList));
|
||||
/**
|
||||
* Persists a {@link SignedMarkRevocationList} instance and returns the persisted entity.
|
||||
*
|
||||
* <p>Note that the input parameter is untouched. Use the returned object if metadata fields like
|
||||
* {@code revisionId} are needed.
|
||||
*/
|
||||
public static SignedMarkRevocationList save(SignedMarkRevocationList signedMarkRevocationList) {
|
||||
var persisted =
|
||||
tm().transact(
|
||||
() -> {
|
||||
var entity =
|
||||
SignedMarkRevocationList.create(
|
||||
signedMarkRevocationList.getCreationTime(),
|
||||
ImmutableMap.copyOf(signedMarkRevocationList.revokes));
|
||||
tm().insert(entity);
|
||||
return entity;
|
||||
});
|
||||
logger.atInfo().log(
|
||||
"Inserted %,d signed mark revocations into Cloud SQL.",
|
||||
signedMarkRevocationList.revokes.size());
|
||||
"Inserted %,d signed mark revocations into Cloud SQL.", persisted.revokes.size());
|
||||
return persisted;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,24 +133,30 @@ public final class PremiumListDao {
|
||||
}
|
||||
|
||||
/** Saves the given premium list (and its premium list entries) to Cloud SQL. */
|
||||
public static PremiumList save(PremiumList premiumList) {
|
||||
tm().transact(
|
||||
() -> {
|
||||
tm().insert(premiumList);
|
||||
tm().getEntityManager().flush(); // This populates the revisionId.
|
||||
long revisionId = premiumList.getRevisionId();
|
||||
public static PremiumList save(PremiumList premiumListToPersist) {
|
||||
PremiumList persisted =
|
||||
tm().transact(
|
||||
() -> {
|
||||
// Make a new copy in each attempt to insert. See javadoc of the insert method for
|
||||
// more information.
|
||||
PremiumList premiumList = premiumListToPersist.asBuilder().build();
|
||||
tm().insert(premiumList);
|
||||
tm().getEntityManager().flush(); // This populates the revisionId.
|
||||
long revisionId = premiumList.getRevisionId();
|
||||
|
||||
if (!isNullOrEmpty(premiumList.getLabelsToPrices())) {
|
||||
ImmutableSet.Builder<PremiumEntry> entries = new ImmutableSet.Builder<>();
|
||||
premiumList
|
||||
.getLabelsToPrices()
|
||||
.forEach(
|
||||
(key, value) -> entries.add(PremiumEntry.create(revisionId, value, key)));
|
||||
tm().insertAll(entries.build());
|
||||
}
|
||||
});
|
||||
premiumListCache.invalidate(premiumList.getName());
|
||||
return premiumList;
|
||||
if (!isNullOrEmpty(premiumList.getLabelsToPrices())) {
|
||||
ImmutableSet.Builder<PremiumEntry> entries = new ImmutableSet.Builder<>();
|
||||
premiumList
|
||||
.getLabelsToPrices()
|
||||
.forEach(
|
||||
(key, value) ->
|
||||
entries.add(PremiumEntry.create(revisionId, value, key)));
|
||||
tm().insertAll(entries.build());
|
||||
}
|
||||
return premiumList;
|
||||
});
|
||||
premiumListCache.invalidate(persisted.getName());
|
||||
return persisted;
|
||||
}
|
||||
|
||||
public static void delete(PremiumList premiumList) {
|
||||
|
||||
@@ -27,14 +27,26 @@ public class ReservedListDao {
|
||||
|
||||
private ReservedListDao() {}
|
||||
|
||||
/** Persist a new reserved list to Cloud SQL. */
|
||||
public static void save(ReservedList reservedList) {
|
||||
/**
|
||||
* Persists a new reserved list to Cloud SQL and returns the persisted entity.
|
||||
*
|
||||
* <p>Note that the input parameter is untouched. Use the returned object if metadata fields like
|
||||
* {@code revisionId} are needed.
|
||||
*/
|
||||
public static ReservedList save(ReservedList reservedList) {
|
||||
checkArgumentNotNull(reservedList, "Must specify reservedList");
|
||||
logger.atInfo().log("Saving reserved list %s to Cloud SQL.", reservedList.getName());
|
||||
tm().transact(() -> tm().insert(reservedList));
|
||||
var persisted =
|
||||
tm().transact(
|
||||
() -> {
|
||||
var entity = reservedList.asBuilder().build();
|
||||
tm().insert(entity);
|
||||
return entity;
|
||||
});
|
||||
logger.atInfo().log(
|
||||
"Saved reserved list %s with %d entries to Cloud SQL.",
|
||||
reservedList.getName(), reservedList.getReservedListEntries().size());
|
||||
return persisted;
|
||||
}
|
||||
|
||||
/** Deletes a reserved list from Cloud SQL. */
|
||||
|
||||
@@ -49,10 +49,23 @@ public class ClaimsListDao {
|
||||
return CacheUtils.newCacheBuilder(expiry).build(ignored -> ClaimsListDao.getUncached());
|
||||
}
|
||||
|
||||
/** Saves the given {@link ClaimsList} to Cloud SQL. */
|
||||
public static void save(ClaimsList claimsList) {
|
||||
tm().transact(() -> tm().insert(claimsList));
|
||||
CACHE.put(ClaimsListDao.class, claimsList);
|
||||
/**
|
||||
* Persists a {@link ClaimsList} instance and returns the persisted entity.
|
||||
*
|
||||
* <p>Note that the input parameter is untouched. Use the returned object if metadata fields like
|
||||
* {@code revisionId} are needed.
|
||||
*/
|
||||
public static ClaimsList save(ClaimsList claimsList) {
|
||||
var persisted =
|
||||
tm().transact(
|
||||
() -> {
|
||||
var entity =
|
||||
ClaimsList.create(claimsList.tmdbGenerationTime, claimsList.labelsToKeys);
|
||||
tm().insert(entity);
|
||||
return entity;
|
||||
});
|
||||
CACHE.put(ClaimsListDao.class, persisted);
|
||||
return persisted;
|
||||
}
|
||||
|
||||
/** Returns the most recent revision of the {@link ClaimsList} from the cache. */
|
||||
|
||||
@@ -344,6 +344,18 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
|
||||
return txnInfo.transactionTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts an object into the database.
|
||||
*
|
||||
* <p>If {@code entity} has an auto-generated identity field (i.e., a field annotated with {@link
|
||||
* jakarta.persistence.GeneratedValue}), the caller must not assign a value to this field,
|
||||
* otherwise Hibernate would mistake the entity as detached and raise an error.
|
||||
*
|
||||
* <p>The practical implication of the above is that when inserting such an entity using a
|
||||
* retriable transaction , the entity should be instantiated inside the transaction body. A failed
|
||||
* attempt may still assign and ID to the entity, therefore reusing the same entity would cause
|
||||
* retries to fail.
|
||||
*/
|
||||
@Override
|
||||
public void insert(Object entity) {
|
||||
checkArgumentNotNull(entity, "entity must be specified");
|
||||
|
||||
@@ -333,7 +333,6 @@ final class RdapDataStructures {
|
||||
*/
|
||||
@RestrictJsonNames("status[]")
|
||||
enum RdapStatus implements Jsonable {
|
||||
|
||||
// Status values specified in RFC 9083 § 10.2.2.
|
||||
VALIDATED("validated"),
|
||||
RENEW_PROHIBITED("renew prohibited"),
|
||||
|
||||
@@ -57,6 +57,9 @@ public class RdapDomainAction extends RdapActionBase {
|
||||
InternetDomainName domainName;
|
||||
try {
|
||||
domainName = validateDomainName(pathSearchString);
|
||||
} catch (DomainFlowUtils.TldDoesNotExistException e) {
|
||||
// A special case where a valid domain name on a nonexistent TLD should return 404
|
||||
throw new NotFoundException(pathSearchString + " not found");
|
||||
} catch (EppException e) {
|
||||
throw new BadRequestException(
|
||||
String.format(
|
||||
|
||||
@@ -14,18 +14,13 @@
|
||||
|
||||
package google.registry.rdap;
|
||||
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.replicaTm;
|
||||
import static google.registry.rdap.RdapUtils.getRegistrarByIanaIdentifier;
|
||||
import static google.registry.rdap.RdapUtils.getRegistrarByName;
|
||||
import static google.registry.request.Action.Method.GET;
|
||||
import static google.registry.request.Action.Method.HEAD;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.primitives.Longs;
|
||||
import com.google.re2j.Pattern;
|
||||
import google.registry.model.contact.Contact;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.rdap.RdapJsonFormatter.OutputDataType;
|
||||
import google.registry.rdap.RdapMetrics.EndpointType;
|
||||
import google.registry.rdap.RdapObjectClasses.RdapEntity;
|
||||
@@ -37,8 +32,8 @@ import jakarta.inject.Inject;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* RDAP action for entity (contact and registrar) requests. the ICANN operational profile dictates
|
||||
* that the "handle" for registrars is to be the IANA registrar ID:
|
||||
* RDAP action for entity (i.e. registrar) requests. the ICANN operational profile dictates that the
|
||||
* "handle" for registrars is to be the IANA registrar ID:
|
||||
*
|
||||
* <p>2.4.1.Registry RDAP servers MUST support Registrar object lookup using an entity path request
|
||||
* for entities with the registrar role using the handle (as described in 3.1.5 of RFC9082) where
|
||||
@@ -52,8 +47,6 @@ import java.util.Optional;
|
||||
auth = Auth.AUTH_PUBLIC)
|
||||
public class RdapEntityAction extends RdapActionBase {
|
||||
|
||||
private static final Pattern ROID_PATTERN = Pattern.compile("[-_.a-zA-Z0-9]+");
|
||||
|
||||
@Inject public RdapEntityAction() {
|
||||
super("entity", EndpointType.ENTITY);
|
||||
}
|
||||
@@ -61,24 +54,6 @@ public class RdapEntityAction extends RdapActionBase {
|
||||
@Override
|
||||
public RdapEntity getJsonObjectForResource(
|
||||
String pathSearchString, boolean isHeadRequest) {
|
||||
// The query string is not used; the RDAP syntax is /rdap/entity/handle (the handle is the roid
|
||||
// for contacts and the client identifier/fn for registrars). Since RDAP's concept of an entity
|
||||
// includes both contacts and registrars, search for one first, then the other.
|
||||
|
||||
// RDAP Technical Implementation Guide 2.3.1 - MUST support contact entity lookup using the
|
||||
// handle
|
||||
if (ROID_PATTERN.matcher(pathSearchString).matches()) {
|
||||
VKey<Contact> contactVKey = VKey.create(Contact.class, pathSearchString);
|
||||
Optional<Contact> contact =
|
||||
replicaTm().transact(() -> replicaTm().loadByKeyIfPresent(contactVKey));
|
||||
// As per Andy Newton on the regext mailing list, contacts by themselves have no role, since
|
||||
// they are global, and might have different roles for different domains.
|
||||
if (contact.isPresent() && isAuthorized(contact.get())) {
|
||||
return rdapJsonFormatter.createRdapContactEntity(
|
||||
contact.get(), ImmutableSet.of(), OutputDataType.FULL);
|
||||
}
|
||||
}
|
||||
|
||||
// RDAP Technical Implementation Guide 2.4.1 - MUST support registrar entity lookup using the
|
||||
// IANA ID as handle
|
||||
Long ianaIdentifier = Longs.tryParse(pathSearchString);
|
||||
@@ -96,7 +71,7 @@ public class RdapEntityAction extends RdapActionBase {
|
||||
return rdapJsonFormatter.createRdapRegistrarEntity(registrar.get(), OutputDataType.FULL);
|
||||
}
|
||||
|
||||
// At this point, we have failed to find either a contact or a registrar.
|
||||
// At this point, we have failed to find a registrar.
|
||||
//
|
||||
// RFC7480 5.3 - if the server wishes to respond that it doesn't have data satisfying the
|
||||
// query, it MUST reply with 404 response code.
|
||||
|
||||
@@ -15,22 +15,16 @@
|
||||
package google.registry.rdap;
|
||||
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.replicaTm;
|
||||
import static google.registry.rdap.RdapUtils.getRegistrarByIanaIdentifier;
|
||||
import static google.registry.request.Action.Method.GET;
|
||||
import static google.registry.request.Action.Method.HEAD;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Streams;
|
||||
import com.google.common.primitives.Booleans;
|
||||
import com.google.common.primitives.Longs;
|
||||
import google.registry.model.contact.Contact;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.persistence.transaction.CriteriaQueryBuilder;
|
||||
import google.registry.rdap.RdapAuthorization.Role;
|
||||
import google.registry.rdap.RdapJsonFormatter.OutputDataType;
|
||||
import google.registry.rdap.RdapMetrics.EndpointType;
|
||||
import google.registry.rdap.RdapMetrics.SearchType;
|
||||
@@ -49,27 +43,12 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* RDAP action for entity (contact and registrar) search requests.
|
||||
* RDAP action for entity (i.e. registrar) search requests.
|
||||
*
|
||||
* <p>All commands and responses conform to the RDAP spec as defined in STD 95 and its RFCs.
|
||||
*
|
||||
* <p>The RDAP specification lumps contacts and registrars together and calls them "entities", which
|
||||
* is confusing for us, because "entity" means something else in SQL. But here, when we use the
|
||||
* term, it means either a contact or registrar. When searching for entities, we always start by
|
||||
* returning all matching contacts, and after that all matching registrars.
|
||||
*
|
||||
* <p>There are two ways to search for entities: by full name (for contacts, the search name, for
|
||||
* registrars, the registrar name) or by handle (for contacts, the ROID, for registrars, the IANA
|
||||
* number). The ICANN operational profile document specifies this meaning for handle searches.
|
||||
*
|
||||
* <p>Cursors are complicated by the fact that we are essentially doing two independent searches:
|
||||
* one for contacts, and one for registrars. To accommodate this, the cursor has a prefix indicating
|
||||
* the type of the last returned item. If the last item was a contact, we return c:{value}, where
|
||||
* the value is either the search name or the ROID. If the last item was a registrar, we return
|
||||
* r:{value}, where the value is either the registrar name or the IANA number. If we get a c:
|
||||
* cursor, we use it to weed out contacts, and fetch all registrars. If we get an r: cursor, we know
|
||||
* that we can skip the contact search altogether (because we returned a registrar, and all
|
||||
* registrars come after all contacts).
|
||||
* <p>There are two ways to search for entities: by full name (the registrar name) or by handle (the
|
||||
* IANA number). The ICANN operational profile document specifies this meaning for handle searches.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc9082">RFC 9082: Registration Data Access Protocol
|
||||
* (RDAP) Query Format</a>
|
||||
@@ -85,31 +64,10 @@ public class RdapEntitySearchAction extends RdapSearchActionBase {
|
||||
|
||||
@Inject @Parameter("fn") Optional<String> fnParam;
|
||||
@Inject @Parameter("handle") Optional<String> handleParam;
|
||||
@Inject @Parameter("subtype") Optional<String> subtypeParam;
|
||||
@Inject public RdapEntitySearchAction() {
|
||||
super("entity search", EndpointType.ENTITIES);
|
||||
}
|
||||
|
||||
private enum QueryType {
|
||||
FULL_NAME,
|
||||
HANDLE
|
||||
}
|
||||
|
||||
private enum Subtype {
|
||||
ALL,
|
||||
CONTACTS,
|
||||
REGISTRARS
|
||||
}
|
||||
|
||||
private enum CursorType {
|
||||
NONE,
|
||||
CONTACT,
|
||||
REGISTRAR
|
||||
}
|
||||
|
||||
private static final String CONTACT_CURSOR_PREFIX = "c:";
|
||||
private static final String REGISTRAR_CURSOR_PREFIX = "r:";
|
||||
|
||||
/** Parses the parameters and calls the appropriate search function. */
|
||||
@Override
|
||||
public EntitySearchResponse getSearchResponse(boolean isHeadRequest) {
|
||||
@@ -118,61 +76,23 @@ public class RdapEntitySearchAction extends RdapSearchActionBase {
|
||||
throw new BadRequestException("You must specify either fn=XXXX or handle=YYYY");
|
||||
}
|
||||
|
||||
// Check the subtype.
|
||||
Subtype subtype;
|
||||
if (subtypeParam.isEmpty() || subtypeParam.get().equalsIgnoreCase("all")) {
|
||||
subtype = Subtype.ALL;
|
||||
} else if (subtypeParam.get().equalsIgnoreCase("contacts")) {
|
||||
subtype = Subtype.CONTACTS;
|
||||
} else if (subtypeParam.get().equalsIgnoreCase("registrars")) {
|
||||
subtype = Subtype.REGISTRARS;
|
||||
} else {
|
||||
throw new BadRequestException("Subtype parameter must specify contacts, registrars or all");
|
||||
}
|
||||
|
||||
CursorType cursorType;
|
||||
Optional<String> cursorQueryString;
|
||||
if (cursorString.isEmpty()) {
|
||||
cursorType = CursorType.NONE;
|
||||
cursorQueryString = Optional.empty();
|
||||
} else {
|
||||
if (cursorString.get().startsWith(CONTACT_CURSOR_PREFIX)) {
|
||||
cursorType = CursorType.CONTACT;
|
||||
cursorQueryString =
|
||||
Optional.of(cursorString.get().substring(CONTACT_CURSOR_PREFIX.length()));
|
||||
} else if (cursorString.get().startsWith(REGISTRAR_CURSOR_PREFIX)) {
|
||||
cursorType = CursorType.REGISTRAR;
|
||||
cursorQueryString =
|
||||
Optional.of(cursorString.get().substring(REGISTRAR_CURSOR_PREFIX.length()));
|
||||
} else {
|
||||
throw new BadRequestException(String.format("invalid cursor: %s", cursorTokenParam));
|
||||
}
|
||||
}
|
||||
|
||||
// Search by name.
|
||||
EntitySearchResponse results;
|
||||
if (fnParam.isPresent()) {
|
||||
metricInformationBuilder.setSearchType(SearchType.BY_FULL_NAME);
|
||||
// syntax: /rdap/entities?fn=Bobby%20Joe*
|
||||
// The name is the contact name or registrar name (not registrar contact name).
|
||||
// The name is the registrar name (not registrar contact name).
|
||||
results =
|
||||
searchByName(
|
||||
recordWildcardType(RdapSearchPattern.createFromUnicodeString(fnParam.get())),
|
||||
cursorType,
|
||||
cursorQueryString,
|
||||
subtype);
|
||||
|
||||
// Search by handle.
|
||||
recordWildcardType(RdapSearchPattern.createFromUnicodeString(fnParam.get())));
|
||||
} else {
|
||||
// Search by handle.
|
||||
metricInformationBuilder.setSearchType(SearchType.BY_HANDLE);
|
||||
// syntax: /rdap/entities?handle=12345-*
|
||||
// The handle is either the contact roid or the registrar clientId.
|
||||
// The handle is the registrar ID.
|
||||
results =
|
||||
searchByHandle(
|
||||
recordWildcardType(RdapSearchPattern.createFromUnicodeString(handleParam.get())),
|
||||
cursorType,
|
||||
cursorQueryString,
|
||||
subtype);
|
||||
recordWildcardType(RdapSearchPattern.createFromUnicodeString(handleParam.get())));
|
||||
}
|
||||
|
||||
// Build the result object and return it.
|
||||
@@ -194,91 +114,32 @@ public class RdapEntitySearchAction extends RdapSearchActionBase {
|
||||
* <p>According to RFC 9082 section 6.1, punycode is only used for domain name labels, so we can
|
||||
* assume that entity names are regular unicode.
|
||||
*
|
||||
* <p>The includeDeleted flag is ignored when searching for contacts, because contact names are
|
||||
* set to null when the contact is deleted, so a deleted contact can never have a name.
|
||||
*
|
||||
* <p>Since we are restricting access to contact names, we don't want name searches to return
|
||||
* contacts whose names are not visible. That would allow unscrupulous users to query by name and
|
||||
* infer that all returned contacts contain that name string. So we check the authorization level
|
||||
* to determine what to do.
|
||||
*
|
||||
* @see <a
|
||||
* href="https://newgtlds.icann.org/sites/default/files/agreements/agreement-approved-09jan14-en.htm">1.6
|
||||
* of Section 4 of the Base Registry Agreement</a>
|
||||
*/
|
||||
private EntitySearchResponse searchByName(
|
||||
final RdapSearchPattern partialStringQuery,
|
||||
CursorType cursorType,
|
||||
Optional<String> cursorQueryString,
|
||||
Subtype subtype) {
|
||||
private EntitySearchResponse searchByName(final RdapSearchPattern partialStringQuery) {
|
||||
// Don't allow wildcard suffixes when searching for entities.
|
||||
if (partialStringQuery.getHasWildcard() && (partialStringQuery.getSuffix() != null)) {
|
||||
throw new UnprocessableEntityException(
|
||||
"Suffixes not allowed in wildcard entity name searches");
|
||||
}
|
||||
// For wildcards, make sure the initial string is long enough, except in the special case of
|
||||
// searching for all registrars, where we aren't worried about inefficient searches.
|
||||
if (partialStringQuery.getHasWildcard()
|
||||
&& (subtype != Subtype.REGISTRARS)
|
||||
&& (partialStringQuery.getInitialString().length()
|
||||
< RdapSearchPattern.MIN_INITIAL_STRING_LENGTH)) {
|
||||
throw new UnprocessableEntityException(
|
||||
"Initial search string required in wildcard entity name searches");
|
||||
}
|
||||
// Get the registrar matches. If we have a registrar cursor, weed out registrars up to and
|
||||
// including the one we ended with last time. We can skip registrars if subtype is CONTACTS.
|
||||
ImmutableList<Registrar> registrars;
|
||||
if (subtype == Subtype.CONTACTS) {
|
||||
registrars = ImmutableList.of();
|
||||
} else {
|
||||
registrars =
|
||||
Streams.stream(Registrar.loadAllCached())
|
||||
.sorted(
|
||||
Comparator.comparing(Registrar::getRegistrarName, String.CASE_INSENSITIVE_ORDER))
|
||||
.filter(
|
||||
registrar ->
|
||||
partialStringQuery.matches(registrar.getRegistrarName())
|
||||
&& ((cursorType != CursorType.REGISTRAR)
|
||||
|| (registrar.getRegistrarName().compareTo(cursorQueryString.get())
|
||||
> 0))
|
||||
&& shouldBeVisible(registrar))
|
||||
.limit(rdapResultSetMaxSize + 1)
|
||||
.collect(toImmutableList());
|
||||
}
|
||||
// Get the contact matches and return the results, fetching an additional contact to detect
|
||||
// truncation. Don't bother searching for contacts by name if the request would not be able to
|
||||
// see any names anyway. Also, if a registrar cursor is present, we have already moved past the
|
||||
// contacts, and don't need to fetch them this time. We can skip contacts if subtype is
|
||||
// REGISTRARS.
|
||||
RdapResultSet<Contact> resultSet;
|
||||
if (subtype == Subtype.REGISTRARS) {
|
||||
resultSet = RdapResultSet.create(ImmutableList.of());
|
||||
} else {
|
||||
if ((rdapAuthorization.role() == RdapAuthorization.Role.PUBLIC)
|
||||
|| (cursorType == CursorType.REGISTRAR)) {
|
||||
resultSet = RdapResultSet.create(ImmutableList.of());
|
||||
} else {
|
||||
resultSet =
|
||||
replicaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
CriteriaQueryBuilder<Contact> builder =
|
||||
queryItems(
|
||||
Contact.class,
|
||||
"searchName",
|
||||
partialStringQuery,
|
||||
cursorQueryString,
|
||||
DeletedItemHandling.EXCLUDE);
|
||||
if (!rdapAuthorization.role().equals(Role.ADMINISTRATOR)) {
|
||||
builder =
|
||||
builder.whereFieldIsIn(
|
||||
"currentSponsorRegistrarId", rdapAuthorization.registrarIds());
|
||||
}
|
||||
return getMatchingResources(builder, false, rdapResultSetMaxSize + 1);
|
||||
});
|
||||
}
|
||||
}
|
||||
return makeSearchResults(resultSet, registrars, QueryType.FULL_NAME);
|
||||
// Get the registrar matches. If we have a cursor, weed out registrars up to and including the
|
||||
// one we ended with last time.
|
||||
ImmutableList<Registrar> registrars =
|
||||
Streams.stream(Registrar.loadAllCached())
|
||||
.sorted(
|
||||
Comparator.comparing(Registrar::getRegistrarName, String.CASE_INSENSITIVE_ORDER))
|
||||
.filter(
|
||||
registrar ->
|
||||
partialStringQuery.matches(registrar.getRegistrarName())
|
||||
&& (cursorString.isEmpty()
|
||||
|| (registrar.getRegistrarName().compareTo(cursorString.get()) > 0))
|
||||
&& shouldBeVisible(registrar))
|
||||
.limit(rdapResultSetMaxSize + 1)
|
||||
.collect(toImmutableList());
|
||||
|
||||
return makeSearchResults(registrars);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -288,101 +149,41 @@ public class RdapEntitySearchAction extends RdapSearchActionBase {
|
||||
*
|
||||
* <p>We don't allow suffixes after a wildcard in entity searches. Suffixes are used in domain
|
||||
* searches to specify a TLD, and in nameserver searches to specify a locally managed domain name.
|
||||
* In both cases, the suffix can be turned into an additional query filter field. For contacts,
|
||||
* there is no equivalent string suffix that can be used as a query filter, so we disallow use.
|
||||
* In both cases, the suffix can be turned into an additional query filter field.
|
||||
*/
|
||||
private EntitySearchResponse searchByHandle(
|
||||
final RdapSearchPattern partialStringQuery,
|
||||
CursorType cursorType,
|
||||
Optional<String> cursorQueryString,
|
||||
Subtype subtype) {
|
||||
private EntitySearchResponse searchByHandle(final RdapSearchPattern partialStringQuery) {
|
||||
if (partialStringQuery.getSuffix() != null) {
|
||||
throw new UnprocessableEntityException("Suffixes not allowed in entity handle searches");
|
||||
}
|
||||
// Handle queries without a wildcard (and not including deleted) -- load by ID.
|
||||
if (!partialStringQuery.getHasWildcard() && !shouldIncludeDeleted()) {
|
||||
ImmutableList<Contact> contactList;
|
||||
if (subtype == Subtype.REGISTRARS) {
|
||||
contactList = ImmutableList.of();
|
||||
} else {
|
||||
Optional<Contact> contact =
|
||||
replicaTm()
|
||||
.transact(
|
||||
() ->
|
||||
replicaTm()
|
||||
.loadByKeyIfPresent(
|
||||
VKey.create(Contact.class, partialStringQuery.getInitialString())));
|
||||
contactList =
|
||||
(contact.isPresent() && shouldBeVisible(contact.get()))
|
||||
? ImmutableList.of(contact.get())
|
||||
: ImmutableList.of();
|
||||
}
|
||||
ImmutableList<Registrar> registrarList;
|
||||
if (subtype == Subtype.CONTACTS) {
|
||||
registrarList = ImmutableList.of();
|
||||
} else {
|
||||
registrarList = getMatchingRegistrars(partialStringQuery.getInitialString());
|
||||
}
|
||||
return makeSearchResults(
|
||||
contactList,
|
||||
IncompletenessWarningType.COMPLETE,
|
||||
contactList.size(),
|
||||
registrarList,
|
||||
QueryType.HANDLE);
|
||||
return makeSearchResults(getMatchingRegistrars(partialStringQuery.getInitialString()));
|
||||
}
|
||||
// Handle queries with a wildcard (or including deleted), but no suffix. Because the handle
|
||||
// for registrars is the IANA identifier number, don't allow wildcard searches for registrars,
|
||||
// by simply not searching for registrars if a wildcard is present (unless the request is for
|
||||
// all registrars, in which case we know what to do). Fetch an extra contact to detect result
|
||||
// set truncation.
|
||||
// all registrars, in which case we know what to do).
|
||||
ImmutableList<Registrar> registrars;
|
||||
if (partialStringQuery.getHasWildcard() && partialStringQuery.getInitialString().isEmpty()) {
|
||||
// Even though we are searching by IANA identifier, we should still sort by name, because
|
||||
// the IANA identifier can by missing, and sorting on that would screw up our cursors.
|
||||
registrars =
|
||||
Streams.stream(Registrar.loadAllCached())
|
||||
.sorted(
|
||||
Comparator.comparing(Registrar::getRegistrarName, String.CASE_INSENSITIVE_ORDER))
|
||||
.filter(
|
||||
registrar ->
|
||||
(cursorString.isEmpty()
|
||||
|| (registrar.getRegistrarName().compareTo(cursorString.get()) > 0))
|
||||
&& shouldBeVisible(registrar))
|
||||
.limit(rdapResultSetMaxSize + 1)
|
||||
.collect(toImmutableList());
|
||||
} else if (partialStringQuery.getHasWildcard()) {
|
||||
registrars = ImmutableList.of();
|
||||
} else {
|
||||
ImmutableList<Registrar> registrars;
|
||||
if ((subtype == Subtype.REGISTRARS)
|
||||
&& partialStringQuery.getHasWildcard()
|
||||
&& partialStringQuery.getInitialString().isEmpty()) {
|
||||
// Even though we are searching by IANA identifier, we should still sort by name, because
|
||||
// the IANA identifier can by missing, and sorting on that would screw up our cursors.
|
||||
registrars =
|
||||
Streams.stream(Registrar.loadAllCached())
|
||||
.sorted(
|
||||
Comparator.comparing(
|
||||
Registrar::getRegistrarName, String.CASE_INSENSITIVE_ORDER))
|
||||
.filter(
|
||||
registrar ->
|
||||
((cursorType != CursorType.REGISTRAR)
|
||||
|| (registrar.getRegistrarName().compareTo(cursorQueryString.get())
|
||||
> 0))
|
||||
&& shouldBeVisible(registrar))
|
||||
.limit(rdapResultSetMaxSize + 1)
|
||||
.collect(toImmutableList());
|
||||
} else if ((subtype == Subtype.CONTACTS) || partialStringQuery.getHasWildcard()) {
|
||||
registrars = ImmutableList.of();
|
||||
} else {
|
||||
registrars = getMatchingRegistrars(partialStringQuery.getInitialString());
|
||||
}
|
||||
// Get the contact matches and return the results, fetching an additional contact to detect
|
||||
// truncation. If we are including deleted entries, we must fetch more entries, in case some
|
||||
// get excluded due to permissioning. Any cursor present must be a contact cursor, because we
|
||||
// would never return a registrar for this search.
|
||||
int querySizeLimit = getStandardQuerySizeLimit();
|
||||
RdapResultSet<Contact> contactResultSet;
|
||||
if (subtype == Subtype.REGISTRARS) {
|
||||
contactResultSet = RdapResultSet.create(ImmutableList.of());
|
||||
} else {
|
||||
contactResultSet =
|
||||
replicaTm()
|
||||
.transact(
|
||||
() ->
|
||||
getMatchingResources(
|
||||
queryItemsByKey(
|
||||
Contact.class,
|
||||
partialStringQuery,
|
||||
cursorQueryString,
|
||||
getDeletedItemHandling()),
|
||||
shouldIncludeDeleted(),
|
||||
querySizeLimit));
|
||||
}
|
||||
return makeSearchResults(contactResultSet, registrars, QueryType.HANDLE);
|
||||
registrars = getMatchingRegistrars(partialStringQuery.getInitialString());
|
||||
}
|
||||
return makeSearchResults(registrars);
|
||||
}
|
||||
|
||||
/** Looks up registrars by handle (i.e. IANA identifier). */
|
||||
@@ -397,90 +198,25 @@ public class RdapEntitySearchAction extends RdapSearchActionBase {
|
||||
: ImmutableList.of();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a JSON array of entity info maps based on the specified contacts and registrars.
|
||||
*
|
||||
* <p>This is a convenience wrapper for the four-argument makeSearchResults; it unpacks the
|
||||
* properties of the {@link RdapResultSet} structure and passes them as separate arguments.
|
||||
*/
|
||||
private EntitySearchResponse makeSearchResults(
|
||||
RdapResultSet<Contact> resultSet, List<Registrar> registrars, QueryType queryType) {
|
||||
return makeSearchResults(
|
||||
resultSet.resources(),
|
||||
resultSet.incompletenessWarningType(),
|
||||
resultSet.numResourcesRetrieved(),
|
||||
registrars,
|
||||
queryType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a JSON array of entity info maps based on the specified contacts and registrars.
|
||||
*
|
||||
* <p>The number of contacts retrieved is recorded for use by the metrics.
|
||||
*
|
||||
* @param contacts the list of contacts which can be returned
|
||||
* @param incompletenessWarningType MIGHT_BE_INCOMPLETE if the list of contacts might be
|
||||
* incomplete; this only matters if the total count of contacts and registrars combined is
|
||||
* less than a full result set's worth
|
||||
* @param numContactsRetrieved the number of contacts retrieved in the process of generating the
|
||||
* results
|
||||
* @param registrars the list of registrars which can be returned
|
||||
* @param queryType whether the query was by full name or by handle
|
||||
* @return an {@link RdapSearchResults} object
|
||||
*/
|
||||
private EntitySearchResponse makeSearchResults(
|
||||
List<Contact> contacts,
|
||||
IncompletenessWarningType incompletenessWarningType,
|
||||
int numContactsRetrieved,
|
||||
List<Registrar> registrars,
|
||||
QueryType queryType) {
|
||||
|
||||
metricInformationBuilder.setNumContactsRetrieved(numContactsRetrieved);
|
||||
|
||||
/** Builds a JSON array of entity info maps based on the specified registrars. */
|
||||
private EntitySearchResponse makeSearchResults(List<Registrar> registrars) {
|
||||
// Determine what output data type to use, depending on whether more than one entity will be
|
||||
// returned.
|
||||
OutputDataType outputDataType =
|
||||
(contacts.size() + registrars.size() > 1) ? OutputDataType.SUMMARY : OutputDataType.FULL;
|
||||
|
||||
// There can be more results than our max size, partially because we have two pools to draw from
|
||||
// (contacts and registrars), and partially because we try to fetch one more than the max size,
|
||||
// so we can tell whether to display the truncation notification.
|
||||
//
|
||||
// Each time we add a contact or registrar to the output data set, remember what the appropriate
|
||||
// cursor would be if it were the last item returned. When we stop adding items, the last cursor
|
||||
// value we remembered will be the right one to pass back.
|
||||
EntitySearchResponse.Builder builder =
|
||||
EntitySearchResponse.builder()
|
||||
.setIncompletenessWarningType(incompletenessWarningType);
|
||||
Optional<String> newCursor = Optional.empty();
|
||||
for (Contact contact : Iterables.limit(contacts, rdapResultSetMaxSize)) {
|
||||
// As per Andy Newton on the regext mailing list, contacts by themselves have no role, since
|
||||
// they are global, and might have different roles for different domains.
|
||||
registrars.size() > 1 ? OutputDataType.SUMMARY : OutputDataType.FULL;
|
||||
EntitySearchResponse.Builder builder = EntitySearchResponse.builder();
|
||||
Iterable<Registrar> limitedRegistrars = Iterables.limit(registrars, rdapResultSetMaxSize);
|
||||
for (Registrar registrar : limitedRegistrars) {
|
||||
builder
|
||||
.entitySearchResultsBuilder()
|
||||
.add(
|
||||
rdapJsonFormatter.createRdapContactEntity(
|
||||
contact, ImmutableSet.of(), outputDataType));
|
||||
newCursor =
|
||||
Optional.of(
|
||||
CONTACT_CURSOR_PREFIX
|
||||
+ ((queryType == QueryType.FULL_NAME)
|
||||
? contact.getSearchName()
|
||||
: contact.getRepoId()));
|
||||
.add(rdapJsonFormatter.createRdapRegistrarEntity(registrar, outputDataType));
|
||||
}
|
||||
if (rdapResultSetMaxSize > contacts.size()) {
|
||||
for (Registrar registrar :
|
||||
Iterables.limit(registrars, rdapResultSetMaxSize - contacts.size())) {
|
||||
builder
|
||||
.entitySearchResultsBuilder()
|
||||
.add(rdapJsonFormatter.createRdapRegistrarEntity(registrar, outputDataType));
|
||||
newCursor = Optional.of(REGISTRAR_CURSOR_PREFIX + registrar.getRegistrarName());
|
||||
}
|
||||
}
|
||||
if (rdapResultSetMaxSize < contacts.size() + registrars.size()) {
|
||||
builder.setNextPageUri(createNavigationUri(newCursor.get()));
|
||||
if (rdapResultSetMaxSize < registrars.size()) {
|
||||
builder.setNextPageUri(
|
||||
createNavigationUri(Iterables.getLast(limitedRegistrars).getRegistrarName()));
|
||||
builder.setIncompletenessWarningType(IncompletenessWarningType.TRUNCATED);
|
||||
return builder.build();
|
||||
} else {
|
||||
builder.setIncompletenessWarningType(IncompletenessWarningType.COMPLETE);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@@ -117,44 +117,4 @@ public class RdapIcannStandardInformation {
|
||||
/** Possibly incomplete notice as a singleton list, for easy use. */
|
||||
static final ImmutableList<Notice> POSSIBLY_INCOMPLETE_NOTICES =
|
||||
ImmutableList.of(POSSIBLY_INCOMPLETE_RESULT_SET_NOTICE);
|
||||
|
||||
/**
|
||||
* Included when requester is not logged in as the owner of the contact being returned.
|
||||
*
|
||||
* <p>>Note: if we were keeping this around, we'd want/need to implement the <a
|
||||
* href="https://datatracker.ietf.org/doc/rfc9537/">official RDAP redaction spec</a> for contacts.
|
||||
* We are getting rid of contacts in 2025 though so this should be unnecessary.
|
||||
*/
|
||||
static final Remark CONTACT_PERSONAL_DATA_HIDDEN_DATA_REMARK =
|
||||
Remark.builder()
|
||||
.setTitle("REDACTED FOR PRIVACY")
|
||||
.setDescription(
|
||||
"Some of the data in this object has been removed.",
|
||||
"Contact personal data is visible only to the owning registrar.")
|
||||
.setType(Remark.Type.OBJECT_REDACTED_AUTHORIZATION)
|
||||
.addLink(
|
||||
Link.builder()
|
||||
.setRel("alternate")
|
||||
.setHref(
|
||||
"https://github.com/google/nomulus/blob/master/docs/rdap.md#authentication")
|
||||
.setType("text/html")
|
||||
.build())
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Included in ALL contact responses, even if the user is authorized.
|
||||
*
|
||||
* <p>>Note: if we were keeping this around, we'd want/need to implement the <a
|
||||
* href="https://datatracker.ietf.org/doc/rfc9537/">official RDAP redaction spec</a> for contacts.
|
||||
* We are getting rid of contacts in 2025 though so this should be unnecessary.
|
||||
*/
|
||||
static final Remark CONTACT_EMAIL_REDACTED_FOR_DOMAIN =
|
||||
Remark.builder()
|
||||
.setTitle("EMAIL REDACTED FOR PRIVACY")
|
||||
.setDescription(
|
||||
"Please query the RDDS service of the Registrar of Record identifies in this output"
|
||||
+ " for information on how to contact the Registrant of the queried domain"
|
||||
+ " name.")
|
||||
.setType(Remark.Type.OBJECT_REDACTED_AUTHORIZATION)
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -18,17 +18,14 @@ import static com.google.common.base.Predicates.not;
|
||||
import static com.google.common.base.Strings.nullToEmpty;
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static com.google.common.collect.ImmutableSetMultimap.toImmutableSetMultimap;
|
||||
import static google.registry.model.EppResourceUtils.isLinked;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.replicaTm;
|
||||
import static google.registry.util.CollectionUtils.union;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSetMultimap;
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.collect.Streams;
|
||||
@@ -40,11 +37,6 @@ import google.registry.config.RegistryConfig.Config;
|
||||
import google.registry.model.CacheUtils;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.adapters.EnumToAttributeAdapter.EppEnum;
|
||||
import google.registry.model.contact.Contact;
|
||||
import google.registry.model.contact.ContactPhoneNumber;
|
||||
import google.registry.model.contact.PostalInfo;
|
||||
import google.registry.model.domain.DesignatedContact;
|
||||
import google.registry.model.domain.DesignatedContact.Type;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
import google.registry.model.eppcommon.Address;
|
||||
@@ -55,19 +47,17 @@ import google.registry.model.registrar.RegistrarAddress;
|
||||
import google.registry.model.registrar.RegistrarPoc;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.model.reporting.HistoryEntryDao;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.rdap.RdapDataStructures.Event;
|
||||
import google.registry.rdap.RdapDataStructures.EventAction;
|
||||
import google.registry.rdap.RdapDataStructures.Link;
|
||||
import google.registry.rdap.RdapDataStructures.Notice;
|
||||
import google.registry.rdap.RdapDataStructures.PublicId;
|
||||
import google.registry.rdap.RdapDataStructures.RdapStatus;
|
||||
import google.registry.rdap.RdapObjectClasses.RdapContactEntity;
|
||||
import google.registry.rdap.RdapObjectClasses.RdapDomain;
|
||||
import google.registry.rdap.RdapObjectClasses.RdapEntity;
|
||||
import google.registry.rdap.RdapObjectClasses.RdapEntity.Role;
|
||||
import google.registry.rdap.RdapObjectClasses.RdapNameserver;
|
||||
import google.registry.rdap.RdapObjectClasses.RdapRegistrarEntity;
|
||||
import google.registry.rdap.RdapObjectClasses.RdapRegistrarPocEntity;
|
||||
import google.registry.rdap.RdapObjectClasses.SecureDns;
|
||||
import google.registry.rdap.RdapObjectClasses.Vcard;
|
||||
import google.registry.rdap.RdapObjectClasses.VcardArray;
|
||||
@@ -134,8 +124,8 @@ public class RdapJsonFormatter {
|
||||
* What type of data to generate.
|
||||
*
|
||||
* <p>Summary data includes only information about the object itself, while full data includes
|
||||
* associated items (e.g. for domains, full data includes the hosts, contacts and history entries
|
||||
* connected with the domain).
|
||||
* associated items (e.g. for domains, full data includes the hosts and history entries connected
|
||||
* with the domain).
|
||||
*
|
||||
* <p>Summary data is appropriate for search queries which return many results, to avoid load on
|
||||
* the system. According to the ICANN operational profile, a remark must be attached to the
|
||||
@@ -260,10 +250,6 @@ public class RdapJsonFormatter {
|
||||
private static final Ordering<Host> HOST_RESOURCE_ORDERING =
|
||||
Ordering.natural().onResultOf(Host::getHostName);
|
||||
|
||||
/** Sets the ordering for designated contacts; order them in a fixed order by contact type. */
|
||||
private static final Ordering<DesignatedContact> DESIGNATED_CONTACT_ORDERING =
|
||||
Ordering.natural().onResultOf(DesignatedContact::getType);
|
||||
|
||||
/** Creates the TOS notice that is added to every reply. */
|
||||
Notice createTosNotice() {
|
||||
String linkValue = makeRdapServletRelativeUrl("help", RdapHelpAction.TOS_PATH);
|
||||
@@ -387,43 +373,6 @@ public class RdapJsonFormatter {
|
||||
.transact(
|
||||
() ->
|
||||
ImmutableSet.copyOf(replicaTm().loadByKeys(domain.getNameservers()).values()));
|
||||
// Load the registrant and other contacts and add them to the data.
|
||||
ImmutableSet<VKey<Contact>> contacts = domain.getReferencedContacts();
|
||||
ImmutableMap<VKey<? extends Contact>, Contact> loadedContacts =
|
||||
contacts.isEmpty()
|
||||
? ImmutableMap.of()
|
||||
: replicaTm().transact(() -> replicaTm().loadByKeysIfPresent(contacts));
|
||||
|
||||
// RDAP Response Profile 2.7.1, 2.7.3 - we MUST have the contacts. 2.7.4 discusses redaction of
|
||||
// fields we don't want to show (as opposed to not having contacts at all) because of GDPR etc.
|
||||
//
|
||||
// The GDPR redaction is handled in createRdapContactEntity.
|
||||
|
||||
// Load all contacts that are present and group them by type (it is common for a single contact
|
||||
// entity to be used across multiple contact types on domain, e.g. registrant and admin).
|
||||
ImmutableSetMultimap<VKey<Contact>, Type> contactsToRoles =
|
||||
domain.getAllContacts().stream()
|
||||
.sorted(DESIGNATED_CONTACT_ORDERING)
|
||||
.collect(
|
||||
toImmutableSetMultimap(
|
||||
DesignatedContact::getContactKey, DesignatedContact::getType));
|
||||
|
||||
// Convert the contact entities to RDAP output contacts (this also converts the contact types
|
||||
// to RDAP roles).
|
||||
for (VKey<Contact> contactKey : contactsToRoles.keySet()) {
|
||||
Set<Role> roles =
|
||||
contactsToRoles.get(contactKey).stream()
|
||||
.map(RdapJsonFormatter::convertContactTypeToRdapRole)
|
||||
.collect(toImmutableSet());
|
||||
if (roles.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
builder
|
||||
.entitiesBuilder()
|
||||
.add(
|
||||
createRdapContactEntity(
|
||||
loadedContacts.get(contactKey), roles, OutputDataType.INTERNAL));
|
||||
}
|
||||
|
||||
// Add the nameservers to the data; the load was kicked off above for efficiency.
|
||||
// RDAP Response Profile 2.8: we MUST have the nameservers
|
||||
@@ -523,134 +472,6 @@ public class RdapJsonFormatter {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a JSON object for a {@link Contact} and associated contact type.
|
||||
*
|
||||
* <p>If the contact isn't present (i.e. because of minimum registration data set), then always
|
||||
* show all of its fields as if they were redacted, and always deny RDAP authorization.
|
||||
*
|
||||
* @param contact the contact resource object from which the JSON object should be created
|
||||
* @param roles the roles of this contact
|
||||
* @param outputDataType whether to generate full or summary data
|
||||
*/
|
||||
RdapContactEntity createRdapContactEntity(
|
||||
Contact contact, Iterable<RdapEntity.Role> roles, OutputDataType outputDataType) {
|
||||
RdapContactEntity.Builder contactBuilder = RdapContactEntity.builder();
|
||||
|
||||
// RDAP Response Profile 2.7.1, 2.7.3 - we MUST have the contacts
|
||||
boolean isAuthorized =
|
||||
rdapAuthorization.isAuthorizedForRegistrar(contact.getCurrentSponsorRegistrarId());
|
||||
|
||||
VcardArray.Builder vcardBuilder = VcardArray.builder();
|
||||
|
||||
if (isAuthorized) {
|
||||
fillRdapContactEntityWhenAuthorized(contactBuilder, vcardBuilder, contact, outputDataType);
|
||||
} else {
|
||||
// GTLD Registration Data Temp Spec 17may18, Appendix A, 2.3, 2.4 and RDAP Response Profile
|
||||
// 2.7.4.1, 2.7.4.2 - the following fields must be redacted:
|
||||
// for REGISTRANT:
|
||||
// handle (ROID), FN (name), TEL (telephone/fax and extension), street, city, postal code
|
||||
// for ADMIN, TECH:
|
||||
// handle (ROID), FN (name), TEL (telephone/fax and extension), Organization, street, city,
|
||||
// state/province, postal code, country
|
||||
//
|
||||
// Note that in theory we have to show the Organization and state/province and country for the
|
||||
// REGISTRANT. For now, we won't do that until we make sure it's really OK for GDPR
|
||||
//
|
||||
// RDAP Response Profile 2.7.4.3: if we redact values from the contact, we MUST include a
|
||||
// remark
|
||||
contactBuilder
|
||||
.remarksBuilder()
|
||||
.add(RdapIcannStandardInformation.CONTACT_PERSONAL_DATA_HIDDEN_DATA_REMARK);
|
||||
contactBuilder.setHandle("");
|
||||
// The VCard format requires a "fn" entry even if it is empty (redacted)
|
||||
vcardBuilder.add(Vcard.create("fn", "text", ""));
|
||||
}
|
||||
|
||||
contactBuilder.setVcardArray(vcardBuilder.build());
|
||||
contactBuilder.rolesBuilder().addAll(roles);
|
||||
|
||||
// RDAP Response Profile 2.7.5.1, 2.7.5.3:
|
||||
// email MUST be omitted, and we MUST have a Remark saying so
|
||||
contactBuilder
|
||||
.remarksBuilder()
|
||||
.add(RdapIcannStandardInformation.CONTACT_EMAIL_REDACTED_FOR_DOMAIN);
|
||||
|
||||
if (outputDataType != OutputDataType.INTERNAL) {
|
||||
// Rdap Response Profile 1.5 must have "last update of RDAP database" response. But this is
|
||||
// only for direct query responses and not for internal objects. I'm not sure why it's in that
|
||||
// section at all...
|
||||
contactBuilder.setLastUpdateOfRdapDatabaseEvent(
|
||||
Event.builder()
|
||||
.setEventAction(EventAction.LAST_UPDATE_OF_RDAP_DATABASE)
|
||||
.setEventDate(getRequestTime())
|
||||
.build());
|
||||
}
|
||||
return contactBuilder.build();
|
||||
}
|
||||
|
||||
private void fillRdapContactEntityWhenAuthorized(
|
||||
RdapContactEntity.Builder contactBuilder,
|
||||
VcardArray.Builder vcardBuilder,
|
||||
Contact contact,
|
||||
OutputDataType outputDataType) {
|
||||
// ROID needs to be redacted if we aren't authorized, so we can't have a self-link for
|
||||
// unauthorized users
|
||||
contactBuilder.linksBuilder().add(makeSelfLink("entity", contact.getRepoId()));
|
||||
// RDAP Response Profile 2.7.3 - we MUST provide a handle set with the ROID, subject to
|
||||
// redaction.
|
||||
contactBuilder.setHandle(contact.getRepoId());
|
||||
if (outputDataType.equals(OutputDataType.FULL)) {
|
||||
// RDAP Response Profile doesn't mention status for contacts, so we only show it if we're both
|
||||
// FULL and Authorized.
|
||||
contactBuilder
|
||||
.statusBuilder()
|
||||
.addAll(
|
||||
makeStatusValueList(
|
||||
isLinked(contact.createVKey(), getRequestTime())
|
||||
? union(contact.getStatusValues(), StatusValue.LINKED)
|
||||
: contact.getStatusValues(),
|
||||
false,
|
||||
contact.getDeletionTime().isBefore(getRequestTime())));
|
||||
// If we are outputting all data (not just summary data), also add events taken from the
|
||||
// history entries. This isn't strictly required.
|
||||
//
|
||||
// We also only add it for authorized users because millisecond times can fingerprint a user
|
||||
// just as much as the handle can.
|
||||
contactBuilder.eventsBuilder().addAll(makeOptionalEvents(contact));
|
||||
} else {
|
||||
// Only show the "summary data remark" if the user is authorized to see this data - because
|
||||
// unauthorized users don't have a self link meaning they can't navigate to the full data.
|
||||
contactBuilder.remarksBuilder().add(RdapIcannStandardInformation.SUMMARY_DATA_REMARK);
|
||||
}
|
||||
// Adding the VCard members when not redacted.
|
||||
//
|
||||
// RDAP Response Profile 2.7.3 - we MUST have FN, ADR, TEL, EMAIL.
|
||||
//
|
||||
// Note that 2.7.5 also says the EMAIL must be omitted, so we'll omit it
|
||||
PostalInfo postalInfo = contact.getInternationalizedPostalInfo();
|
||||
if (postalInfo == null) {
|
||||
postalInfo = contact.getLocalizedPostalInfo();
|
||||
}
|
||||
if (postalInfo != null) {
|
||||
if (postalInfo.getName() != null) {
|
||||
vcardBuilder.add(Vcard.create("fn", "text", postalInfo.getName()));
|
||||
}
|
||||
if (postalInfo.getOrg() != null) {
|
||||
vcardBuilder.add(Vcard.create("org", "text", postalInfo.getOrg()));
|
||||
}
|
||||
addVCardAddressEntry(vcardBuilder, postalInfo.getAddress());
|
||||
}
|
||||
ContactPhoneNumber voicePhoneNumber = contact.getVoiceNumber();
|
||||
if (voicePhoneNumber != null) {
|
||||
vcardBuilder.add(makePhoneEntry(PHONE_TYPE_VOICE, makePhoneString(voicePhoneNumber)));
|
||||
}
|
||||
ContactPhoneNumber faxPhoneNumber = contact.getFaxNumber();
|
||||
if (faxPhoneNumber != null) {
|
||||
vcardBuilder.add(makePhoneEntry(PHONE_TYPE_FAX, makePhoneString(faxPhoneNumber)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a JSON object for a {@link Registrar}.
|
||||
*
|
||||
@@ -740,38 +561,37 @@ public class RdapJsonFormatter {
|
||||
|
||||
builder.setVcardArray(vcardBuilder.build());
|
||||
|
||||
// Registrar contacts are a bit complicated.
|
||||
// Registrar POCs are a bit complicated.
|
||||
//
|
||||
// Rdap Response Profile 3.2, we SHOULD have at least ADMIN and TECH contacts. It says
|
||||
// Rdap Response Profile 3.2, we SHOULD have at least ADMIN and TECH POCs. It says
|
||||
// nothing about ABUSE at all.
|
||||
//
|
||||
// Rdap Response Profile 4.3 doesn't mention contacts at all, meaning probably we don't have to
|
||||
// have any contacts there. But the Registrar itself is Optional in that case, so we will just
|
||||
// Rdap Response Profile 4.3 doesn't mention POCs at all, meaning probably we don't have to
|
||||
// have any POCs there. But the Registrar itself is Optional in that case, so we will just
|
||||
// skip it completely.
|
||||
//
|
||||
// Rdap Response Profile 2.4.5 says the Registrar inside a Domain response MUST include the
|
||||
// ABUSE contact, but doesn't require any other contact.
|
||||
// ABUSE POC, but doesn't require any other POCs.
|
||||
//
|
||||
// Write the minimum, meaning only ABUSE for INTERNAL registrars, nothing for SUMMARY and
|
||||
// everything for FULL.
|
||||
if (outputDataType != OutputDataType.SUMMARY) {
|
||||
ImmutableList<RdapContactEntity> registrarContacts =
|
||||
registrar.getContactsFromReplica().stream()
|
||||
.map(RdapJsonFormatter::makeRdapJsonForRegistrarContact)
|
||||
ImmutableList<RdapRegistrarPocEntity> registrarPocs =
|
||||
registrar.getPocsFromReplica().stream()
|
||||
.map(RdapJsonFormatter::makeRdapJsonForRegistrarPoc)
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.filter(
|
||||
contact ->
|
||||
poc ->
|
||||
outputDataType == OutputDataType.FULL
|
||||
|| contact.roles().contains(RdapEntity.Role.ABUSE))
|
||||
|| poc.roles().contains(RdapEntity.Role.ABUSE))
|
||||
.collect(toImmutableList());
|
||||
if (registrarContacts.stream()
|
||||
.noneMatch(contact -> contact.roles().contains(RdapEntity.Role.ABUSE))) {
|
||||
if (registrarPocs.stream().noneMatch(poc -> poc.roles().contains(RdapEntity.Role.ABUSE))) {
|
||||
logger.atWarning().log(
|
||||
"Registrar '%s' (IANA ID %s) is missing ABUSE contact.",
|
||||
"Registrar '%s' (IANA ID %s) is missing ABUSE POC.",
|
||||
registrar.getRegistrarId(), registrar.getIanaIdentifier());
|
||||
}
|
||||
builder.entitiesBuilder().addAll(registrarContacts);
|
||||
builder.entitiesBuilder().addAll(registrarPocs);
|
||||
}
|
||||
|
||||
// Rdap Response Profile 1.5, must have "last update of RDAP database" response. But this is
|
||||
@@ -789,7 +609,7 @@ public class RdapJsonFormatter {
|
||||
/**
|
||||
* Creates a JSON object for a {@link RegistrarPoc}.
|
||||
*
|
||||
* <p>Returns empty if this contact shouldn't be visible (doesn't have a role).
|
||||
* <p>Returns empty if this POC shouldn't be visible (doesn't have a role).
|
||||
*
|
||||
* <p>NOTE that registrar locations in the response require different roles and different VCard
|
||||
* members according to the spec. Currently, this function returns all the rolls and all the
|
||||
@@ -799,19 +619,18 @@ public class RdapJsonFormatter {
|
||||
* <p>Specifically:
|
||||
* <li>Registrar inside a Domain only requires the ABUSE role, and only the TEL and EMAIL members
|
||||
* (RDAP Response Profile 2.4.5)
|
||||
* <li>Registrar responses to direct query don't require any contact, but *should* have the TECH
|
||||
* and ADMIN roles, but require the FN, TEL and EMAIL members
|
||||
* <li>Registrar inside a Nameserver isn't required at all, and if given doesn't require any
|
||||
* contacts
|
||||
* <li>Registrar responses to direct query don't require any POCs, but *should* have the TECH and
|
||||
* ADMIN roles, but require the FN, TEL and EMAIL members
|
||||
* <li>Registrar inside a Nameserver isn't required at all, and if given doesn't require any POCs
|
||||
*
|
||||
* @param registrarPoc the registrar contact for which the JSON object should be created
|
||||
* @param registrarPoc the registrar POC for which the JSON object should be created
|
||||
*/
|
||||
static Optional<RdapContactEntity> makeRdapJsonForRegistrarContact(RegistrarPoc registrarPoc) {
|
||||
static Optional<RdapRegistrarPocEntity> makeRdapJsonForRegistrarPoc(RegistrarPoc registrarPoc) {
|
||||
ImmutableList<RdapEntity.Role> roles = makeRdapRoleList(registrarPoc);
|
||||
if (roles.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
RdapContactEntity.Builder builder = RdapContactEntity.builder();
|
||||
RdapRegistrarPocEntity.Builder builder = RdapRegistrarPocEntity.builder();
|
||||
builder.statusBuilder().addAll(STATUS_LIST_ACTIVE);
|
||||
builder.rolesBuilder().addAll(roles);
|
||||
// Create the vCard.
|
||||
@@ -838,20 +657,10 @@ public class RdapJsonFormatter {
|
||||
return Optional.of(builder.build());
|
||||
}
|
||||
|
||||
/** Converts a domain registry contact type into a role as defined by RFC 9083. */
|
||||
private static RdapEntity.Role convertContactTypeToRdapRole(DesignatedContact.Type contactType) {
|
||||
return switch (contactType) {
|
||||
case REGISTRANT -> RdapEntity.Role.REGISTRANT;
|
||||
case TECH -> RdapEntity.Role.TECH;
|
||||
case BILLING -> RdapEntity.Role.BILLING;
|
||||
case ADMIN -> RdapEntity.Role.ADMIN;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the list of RDAP roles for a registrar contact, using the visibleInWhoisAs* flags.
|
||||
* Creates the list of RDAP roles for a registrar POC, using the visibleInWhoisAs* flags.
|
||||
*
|
||||
* <p>Only contacts with a non-empty role list should be visible.
|
||||
* <p>Only POCs with a non-empty role list should be visible.
|
||||
*
|
||||
* <p>The RDAP response profile only mandates the "abuse" entity:
|
||||
*
|
||||
@@ -929,7 +738,7 @@ public class RdapJsonFormatter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the list of optional events to list in domain, nameserver, or contact replies.
|
||||
* Creates the list of optional events to list in domain or nameserver replies.
|
||||
*
|
||||
* <p>Only has entries for optional events that won't be shown in "SUMMARY" versions of these
|
||||
* objects. These are either stated as optional in the RDAP Response Profile, or not mentioned at
|
||||
@@ -1055,15 +864,6 @@ public class RdapJsonFormatter {
|
||||
return Vcard.create("tel", type, "uri", phoneNumber);
|
||||
}
|
||||
|
||||
/** Creates a phone string in URI format, as per the vCard spec. */
|
||||
private static String makePhoneString(ContactPhoneNumber phoneNumber) {
|
||||
String phoneString = String.format("tel:%s", phoneNumber.getPhoneNumber());
|
||||
if (phoneNumber.getExtension() != null) {
|
||||
phoneString = phoneString + ";ext=" + phoneNumber.getExtension();
|
||||
}
|
||||
return phoneString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string array of status values.
|
||||
*
|
||||
|
||||
@@ -133,16 +133,6 @@ public class RdapMetrics {
|
||||
LABEL_DESCRIPTORS_FOR_RETRIEVAL_COUNTS,
|
||||
FIBONACCI_FITTER);
|
||||
|
||||
@VisibleForTesting
|
||||
static final EventMetric numberOfContactsRetrieved =
|
||||
MetricRegistryImpl.getDefault()
|
||||
.newEventMetric(
|
||||
"/rdap/num_contacts_retrieved",
|
||||
"Number of contacts retrieved",
|
||||
"count",
|
||||
LABEL_DESCRIPTORS_FOR_RETRIEVAL_COUNTS,
|
||||
FIBONACCI_FITTER);
|
||||
|
||||
@Inject
|
||||
public RdapMetrics() {}
|
||||
|
||||
@@ -191,15 +181,6 @@ public class RdapMetrics {
|
||||
getLabelStringForPrefixLength(rdapMetricInformation.prefixLength()),
|
||||
rdapMetricInformation.includeDeleted() ? "YES" : "NO");
|
||||
}
|
||||
if (rdapMetricInformation.numContactsRetrieved().isPresent()) {
|
||||
numberOfContactsRetrieved.record(
|
||||
rdapMetricInformation.numContactsRetrieved().get(),
|
||||
rdapMetricInformation.endpointType().toString(),
|
||||
rdapMetricInformation.searchType().toString(),
|
||||
rdapMetricInformation.wildcardType().toString(),
|
||||
getLabelStringForPrefixLength(rdapMetricInformation.prefixLength()),
|
||||
rdapMetricInformation.includeDeleted() ? "YES" : "NO");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -221,10 +202,8 @@ public class RdapMetrics {
|
||||
* than were actually returned in the response; absent if a search was not performed.
|
||||
* @param numHostsRetrieved Number of hosts retrieved from the database; this might be more than
|
||||
* were actually returned in the response; absent if a search was not performed.
|
||||
* @param numContactsRetrieved Number of contacts retrieved from the database; this might be more
|
||||
* than were actually returned in the response; absent if a search was not performed.
|
||||
*/
|
||||
record RdapMetricInformation(
|
||||
public record RdapMetricInformation(
|
||||
EndpointType endpointType,
|
||||
SearchType searchType,
|
||||
WildcardType wildcardType,
|
||||
@@ -236,8 +215,7 @@ public class RdapMetrics {
|
||||
int statusCode,
|
||||
IncompletenessWarningType incompletenessWarningType,
|
||||
Optional<Long> numDomainsRetrieved,
|
||||
Optional<Long> numHostsRetrieved,
|
||||
Optional<Long> numContactsRetrieved) {
|
||||
Optional<Long> numHostsRetrieved) {
|
||||
|
||||
@AutoBuilder
|
||||
interface Builder {
|
||||
@@ -265,8 +243,6 @@ public class RdapMetrics {
|
||||
|
||||
Builder setNumHostsRetrieved(long numHostsRetrieved);
|
||||
|
||||
Builder setNumContactsRetrieved(long numContactRetrieved);
|
||||
|
||||
RdapMetricInformation build();
|
||||
}
|
||||
|
||||
|
||||
@@ -253,8 +253,8 @@ final class RdapObjectClasses {
|
||||
/**
|
||||
* The Entity Object Class defined in 5.1 of RFC 9083.
|
||||
*
|
||||
* <p>Entities are used both for Contacts and for Registrars. We will create different subobjects
|
||||
* for each one for type safety.
|
||||
* <p>Entities are used both for Registrar POCs and for Registrars. We will create different
|
||||
* subobjects for each one for type safety.
|
||||
*
|
||||
* <p>We're missing the "autnums" and "networks" fields
|
||||
*/
|
||||
@@ -309,8 +309,8 @@ final class RdapObjectClasses {
|
||||
/**
|
||||
* Registrar version of the Entity Object Class defined in 5.1 of RFC 9083.
|
||||
*
|
||||
* <p>Entities are used both for Contacts and for Registrars. We will create different subobjects
|
||||
* for each one for type safety.
|
||||
* <p>Entities are used both for Registrar POCs and for Registrars. We will create different
|
||||
* subobjects for each one for type safety.
|
||||
*/
|
||||
@AutoValue
|
||||
public abstract static class RdapRegistrarEntity extends RdapEntity {
|
||||
@@ -326,21 +326,21 @@ final class RdapObjectClasses {
|
||||
}
|
||||
|
||||
/**
|
||||
* Contact version of the Entity Object Class defined in 5.1 of RFC 9083.
|
||||
* RegistrarPoc version of the Entity Object Class defined in 5.1 of RFC 9083.
|
||||
*
|
||||
* <p>Entities are used both for Contacts and for Registrars. We will create different subobjects
|
||||
* for each one for type safety.
|
||||
* <p>Entities are used both for Registrar POCs and for Registrars. We will create different
|
||||
* subobjects for each one for type safety.
|
||||
*/
|
||||
@AutoValue
|
||||
public abstract static class RdapContactEntity extends RdapEntity {
|
||||
public abstract static class RdapRegistrarPocEntity extends RdapEntity {
|
||||
|
||||
static Builder builder() {
|
||||
return new AutoValue_RdapObjectClasses_RdapContactEntity.Builder();
|
||||
return new AutoValue_RdapObjectClasses_RdapRegistrarPocEntity.Builder();
|
||||
}
|
||||
|
||||
@AutoValue.Builder
|
||||
abstract static class Builder extends RdapEntity.Builder<Builder> {
|
||||
abstract RdapContactEntity build();
|
||||
abstract RdapRegistrarPocEntity build();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ abstract class RdapSearchResults {
|
||||
}
|
||||
|
||||
@AutoValue
|
||||
abstract static class EntitySearchResponse extends BaseSearchResponse {
|
||||
public abstract static class EntitySearchResponse extends BaseSearchResponse {
|
||||
|
||||
@JsonableElement public abstract ImmutableList<RdapEntity> entitySearchResults();
|
||||
|
||||
|
||||
@@ -18,11 +18,12 @@ import static com.google.common.base.Throwables.getRootCause;
|
||||
import static google.registry.request.Action.Method.POST;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
|
||||
import com.google.cloud.storage.BlobId;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.google.common.io.ByteStreams;
|
||||
@@ -41,7 +42,6 @@ import jakarta.inject.Inject;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/** Copy all registrar detail reports in a given bucket's subdirectory from GCS to Drive. */
|
||||
@Action(
|
||||
@@ -98,7 +98,8 @@ public final class CopyDetailReportsAction implements Runnable {
|
||||
response.setPayload(String.format("Failure, encountered %s", e.getMessage()));
|
||||
return;
|
||||
}
|
||||
ImmutableMap.Builder<String, Throwable> copyErrorsBuilder = new ImmutableMap.Builder<>();
|
||||
ImmutableMultimap.Builder<String, Throwable> copyErrorsBuilder =
|
||||
new ImmutableMultimap.Builder<>();
|
||||
for (String detailReportName : detailReportObjectNames) {
|
||||
// The standard report format is "invoice_details_yyyy-MM_registrarId_tld.csv
|
||||
// TODO(larryruili): Determine a safer way of enforcing this.
|
||||
@@ -145,17 +146,18 @@ public final class CopyDetailReportsAction implements Runnable {
|
||||
response.setStatus(SC_OK);
|
||||
response.setContentType(MediaType.PLAIN_TEXT_UTF_8);
|
||||
StringBuilder payload = new StringBuilder().append("Copied detail reports.\n");
|
||||
ImmutableMap<String, Throwable> copyErrors = copyErrorsBuilder.build();
|
||||
ImmutableMultimap<String, Throwable> copyErrors = copyErrorsBuilder.build();
|
||||
if (!copyErrors.isEmpty()) {
|
||||
payload.append("The following errors were encountered:\n");
|
||||
payload.append(
|
||||
copyErrors.entrySet().stream()
|
||||
.map(
|
||||
entrySet ->
|
||||
String.format(
|
||||
"Registrar: %s\nError: %s\n",
|
||||
entrySet.getKey(), entrySet.getValue().getMessage()))
|
||||
.collect(Collectors.joining()));
|
||||
for (var registrarId : copyErrors.keySet()) {
|
||||
payload.append(
|
||||
String.format(
|
||||
"Registrar: %s\nError: %s\n",
|
||||
registrarId,
|
||||
copyErrors.get(registrarId).stream()
|
||||
.map(Throwable::getMessage)
|
||||
.collect(joining("\n\t"))));
|
||||
}
|
||||
}
|
||||
response.setPayload(payload.toString());
|
||||
emailUtils.sendAlertEmail(payload.toString());
|
||||
|
||||
@@ -135,7 +135,8 @@ public final class RequestModule {
|
||||
@Provides
|
||||
@RequestUrl
|
||||
static String provideRequestUrl(HttpServletRequest req) {
|
||||
return req.getRequestURL().toString();
|
||||
String url = req.getRequestURL().toString();
|
||||
return url.startsWith("https") ? url : url.replaceFirst("http", "https");
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -30,6 +30,7 @@ import google.registry.request.auth.AuthModule.IapOidc;
|
||||
import google.registry.request.auth.AuthModule.RegularOidc;
|
||||
import google.registry.request.auth.AuthSettings.AuthLevel;
|
||||
import google.registry.util.RegistryEnvironment;
|
||||
import google.registry.util.StopwatchLogger;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.Optional;
|
||||
@@ -77,7 +78,9 @@ public abstract class OidcTokenAuthenticationMechanism implements Authentication
|
||||
logger.atWarning().log("Using AuthResult %s for testing.", authResultForTesting);
|
||||
return authResultForTesting;
|
||||
}
|
||||
final StopwatchLogger stopwatch = new StopwatchLogger();
|
||||
String rawIdToken = tokenExtractor.extract(request);
|
||||
stopwatch.tick("OidcTokenAuthenticationMechanism tokenExtractor extracted");
|
||||
if (rawIdToken == null) {
|
||||
return AuthResult.NOT_AUTHENTICATED;
|
||||
}
|
||||
@@ -99,7 +102,7 @@ public abstract class OidcTokenAuthenticationMechanism implements Authentication
|
||||
? "Raw token redacted in prod"
|
||||
: rawIdToken);
|
||||
}
|
||||
|
||||
stopwatch.tick("OidcTokenAuthenticationMechanism token verified");
|
||||
if (token == null) {
|
||||
return AuthResult.NOT_AUTHENTICATED;
|
||||
}
|
||||
@@ -111,6 +114,7 @@ public abstract class OidcTokenAuthenticationMechanism implements Authentication
|
||||
}
|
||||
Optional<User> maybeUser =
|
||||
tm().transact(() -> tm().loadByKeyIfPresent(VKey.create(User.class, email)));
|
||||
stopwatch.tick("OidcTokenAuthenticationMechanism maybeUser loaded");
|
||||
if (maybeUser.isPresent()) {
|
||||
return AuthResult.createUser(maybeUser.get());
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import google.registry.keyring.api.KeyModule.Key;
|
||||
import google.registry.model.smd.SignedMarkRevocationList;
|
||||
import google.registry.model.smd.SignedMarkRevocationListDao;
|
||||
import google.registry.request.Action;
|
||||
import google.registry.request.Action.GaeService;
|
||||
import google.registry.request.auth.Auth;
|
||||
@@ -57,7 +58,7 @@ public final class TmchSmdrlAction implements Runnable {
|
||||
} catch (GeneralSecurityException | IOException | PGPException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
smdrl.save();
|
||||
smdrl = SignedMarkRevocationListDao.save(smdrl);
|
||||
logger.atInfo().log(
|
||||
"Inserted %,d smd revocations into the database, created at %s.",
|
||||
smdrl.size(), smdrl.getCreationTime());
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
package google.registry.tools;
|
||||
|
||||
|
||||
import com.beust.jcommander.Parameter;
|
||||
import com.beust.jcommander.Parameters;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
@@ -52,11 +51,6 @@ class LoadTestCommand extends ConfirmingCommand implements CommandWithConnection
|
||||
description = "Number of domains to create per second.")
|
||||
int successfulDomainCreates = 1;
|
||||
|
||||
@Parameter(
|
||||
names = {"--successful_contact_creates"},
|
||||
description = "Number of contact records to create per second.")
|
||||
int successfulContactCreates = 1;
|
||||
|
||||
@Parameter(
|
||||
names = {"--host_infos"},
|
||||
description = "Number of successful host:info commands to send per second.")
|
||||
@@ -67,11 +61,6 @@ class LoadTestCommand extends ConfirmingCommand implements CommandWithConnection
|
||||
description = "Number of successful domain:info commands to send per second.")
|
||||
int domainInfos = 1;
|
||||
|
||||
@Parameter(
|
||||
names = {"--contact_infos"},
|
||||
description = "Number of successful contact:info commands to send per second.")
|
||||
int contactInfos = 1;
|
||||
|
||||
@Parameter(
|
||||
names = {"--run_seconds"},
|
||||
description = "Time to run the load test in seconds.")
|
||||
@@ -120,10 +109,8 @@ class LoadTestCommand extends ConfirmingCommand implements CommandWithConnection
|
||||
.put("clientId", clientId)
|
||||
.put("successfulHostCreates", successfulHostCreates)
|
||||
.put("successfulDomainCreates", successfulDomainCreates)
|
||||
.put("successfulContactCreates", successfulContactCreates)
|
||||
.put("hostInfos", hostInfos)
|
||||
.put("domainInfos", domainInfos)
|
||||
.put("contactInfos", contactInfos)
|
||||
.put("runSeconds", runSeconds)
|
||||
.build();
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.io.CharStreams;
|
||||
import com.google.common.net.MediaType;
|
||||
import com.google.re2j.Pattern;
|
||||
import google.registry.config.RegistryConfig.Config;
|
||||
import google.registry.request.Action.GaeService;
|
||||
import google.registry.request.Action.GkeService;
|
||||
@@ -56,9 +55,6 @@ import org.json.simple.JSONValue;
|
||||
*/
|
||||
public class ServiceConnection {
|
||||
|
||||
/** Pattern to heuristically extract title tag contents in HTML responses. */
|
||||
protected static final Pattern HTML_TITLE_TAG_PATTERN = Pattern.compile("<title>(.*?)</title>");
|
||||
|
||||
private final Service service;
|
||||
private final boolean useCanary;
|
||||
private final HttpRequestFactory requestFactory;
|
||||
|
||||
@@ -63,6 +63,7 @@ public class PasswordResetVerifyAction extends ConsoleApiAction {
|
||||
// Temporary flag when testing email sending etc
|
||||
if (!user.getUserRoles().isAdmin()) {
|
||||
setFailedResponse("", HttpServletResponse.SC_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
PasswordResetRequest request = tm().transact(() -> loadAndValidateResetRequest(user));
|
||||
ImmutableMap<String, ?> result =
|
||||
@@ -76,6 +77,7 @@ public class PasswordResetVerifyAction extends ConsoleApiAction {
|
||||
// Temporary flag when testing email sending etc
|
||||
if (!user.getUserRoles().isAdmin()) {
|
||||
setFailedResponse("", HttpServletResponse.SC_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
checkArgument(!Strings.isNullOrEmpty(newPassword.orElse(null)), "Password must be provided");
|
||||
tm().transact(
|
||||
|
||||
@@ -53,8 +53,10 @@ import java.util.Optional;
|
||||
public class RegistrarsAction extends ConsoleApiAction {
|
||||
private static final int PASSWORD_LENGTH = 16;
|
||||
private static final int PASSCODE_LENGTH = 5;
|
||||
private static final ImmutableList<Registrar.Type> allowedRegistrarTypes =
|
||||
ImmutableList.of(Registrar.Type.REAL, Registrar.Type.OTE);
|
||||
private static final ImmutableSet<Registrar.Type> TYPES_ALLOWED_FOR_USERS =
|
||||
ImmutableSet.of(Registrar.Type.REAL, Registrar.Type.OTE);
|
||||
private static final ImmutableSet<Registrar.Type> TYPES_ALLOWED_FOR_ADMINS =
|
||||
ImmutableSet.of(Registrar.Type.INTERNAL, Registrar.Type.REAL, Registrar.Type.OTE);
|
||||
private static final String SQL_TEMPLATE =
|
||||
"""
|
||||
SELECT * FROM "Registrar"
|
||||
@@ -80,6 +82,8 @@ public class RegistrarsAction extends ConsoleApiAction {
|
||||
@Override
|
||||
protected void getHandler(User user) {
|
||||
if (user.getUserRoles().hasGlobalPermission(ConsolePermission.VIEW_REGISTRARS)) {
|
||||
ImmutableSet<Registrar.Type> allowedRegistrarTypes =
|
||||
user.getUserRoles().isAdmin() ? TYPES_ALLOWED_FOR_ADMINS : TYPES_ALLOWED_FOR_USERS;
|
||||
ImmutableList<Registrar> registrars =
|
||||
Streams.stream(Registrar.loadAll())
|
||||
.filter(r -> allowedRegistrarTypes.contains(r.getType()))
|
||||
@@ -94,6 +98,7 @@ public class RegistrarsAction extends ConsoleApiAction {
|
||||
.map(Map.Entry::getKey)
|
||||
.collect(toImmutableSet());
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Registrar> registrars =
|
||||
tm().transact(
|
||||
() ->
|
||||
|
||||
@@ -120,7 +120,7 @@ public class SecurityAction extends ConsoleApiAction {
|
||||
}
|
||||
}
|
||||
} catch (InsecureCertificateException e) {
|
||||
setFailedResponse("Invalid certificate in parameter", SC_BAD_REQUEST);
|
||||
setFailedResponse(e.getMessage(), SC_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ final class DomainWhoisResponse extends WhoisResponseImpl {
|
||||
domain.getCurrentSponsorRegistrarId());
|
||||
Registrar registrar = registrarOptional.get();
|
||||
Optional<RegistrarPoc> abuseContact =
|
||||
registrar.getContactsFromReplica().stream()
|
||||
registrar.getPocsFromReplica().stream()
|
||||
.filter(RegistrarPoc::getVisibleInDomainWhoisAsAbuse)
|
||||
.findFirst();
|
||||
return WhoisResponseResults.create(
|
||||
|
||||
@@ -44,7 +44,7 @@ class RegistrarWhoisResponse extends WhoisResponseImpl {
|
||||
|
||||
@Override
|
||||
public WhoisResponseResults getResponse(boolean preferUnicode, String disclaimer) {
|
||||
Set<RegistrarPoc> contacts = registrar.getContactsFromReplica();
|
||||
Set<RegistrarPoc> contacts = registrar.getPocsFromReplica();
|
||||
String plaintext =
|
||||
new RegistrarEmitter()
|
||||
.emitField("Registrar", registrar.getRegistrarName())
|
||||
|
||||
@@ -24,7 +24,6 @@ import static google.registry.bsa.persistence.BsaTestingUtils.persistDownloadSch
|
||||
import static google.registry.bsa.persistence.BsaTestingUtils.persistUnblockableDomain;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
|
||||
import static google.registry.testing.DatabaseHelper.persistDeletedDomain;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
@@ -218,7 +217,8 @@ public class BsaValidateActionTest {
|
||||
test1,1;2
|
||||
test2,3
|
||||
""";
|
||||
String blockPlusContent = """
|
||||
String blockPlusContent =
|
||||
"""
|
||||
domainLabel,orderIDs
|
||||
test2,4
|
||||
""";
|
||||
@@ -239,7 +239,7 @@ public class BsaValidateActionTest {
|
||||
persistBsaLabel("label");
|
||||
Domain domain = persistActiveDomain("label.app", fakeClock.nowUtc());
|
||||
fakeClock.advanceBy(MAX_STALENESS.minus(Duration.standardSeconds(1)));
|
||||
assertThat(action.isStalenessAllowed(true, domain.createVKey())).isTrue();
|
||||
assertThat(action.isStalenessAllowed(domain.createVKey())).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -247,23 +247,7 @@ public class BsaValidateActionTest {
|
||||
persistBsaLabel("label");
|
||||
Domain domain = persistActiveDomain("label.app", fakeClock.nowUtc());
|
||||
fakeClock.advanceBy(MAX_STALENESS);
|
||||
assertThat(action.isStalenessAllowed(true, domain.createVKey())).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isStalenessAllowed_deletedDomain_allowed() {
|
||||
persistBsaLabel("label");
|
||||
Domain domain = persistDeletedDomain("label.app", fakeClock.nowUtc());
|
||||
fakeClock.advanceBy(MAX_STALENESS.minus(Duration.standardSeconds(1)));
|
||||
assertThat(action.isStalenessAllowed(false, domain.createVKey())).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isStalenessAllowed_deletedDomain_notAllowed() {
|
||||
persistBsaLabel("label");
|
||||
Domain domain = persistDeletedDomain("label.app", fakeClock.nowUtc());
|
||||
fakeClock.advanceBy(MAX_STALENESS);
|
||||
assertThat(action.isStalenessAllowed(false, domain.createVKey())).isFalse();
|
||||
assertThat(action.isStalenessAllowed(domain.createVKey())).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -405,10 +389,11 @@ public class BsaValidateActionTest {
|
||||
assertThat(message.body())
|
||||
.isEqualTo(
|
||||
"""
|
||||
Most recent download is 2023-11-09t020857.880z.
|
||||
Most recent download is 2023-11-09t020857.880z.
|
||||
|
||||
Error line 1.
|
||||
Error line 2""");
|
||||
Error line 1.
|
||||
Error line 2\
|
||||
""");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -20,13 +20,24 @@ import static google.registry.testing.DatabaseHelper.persistActiveDomain;
|
||||
import static google.registry.testing.DatabaseHelper.persistDeletedDomain;
|
||||
import static google.registry.testing.DatabaseHelper.persistReservedList;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.testing.LogsSubject.assertAboutLogs;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
import static google.registry.util.NetworkUtils.pickUnusedPort;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.util.concurrent.Executors.newSingleThreadExecutor;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import com.google.cloud.storage.BlobId;
|
||||
import com.google.cloud.storage.contrib.nio.testing.LocalStorageHelper;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.common.net.HostAndPort;
|
||||
import com.google.common.testing.TestLogHandler;
|
||||
import com.google.gson.Gson;
|
||||
import google.registry.bsa.api.BsaCredential;
|
||||
import google.registry.gcs.GcsUtils;
|
||||
import google.registry.model.tld.Tld;
|
||||
@@ -35,9 +46,25 @@ import google.registry.model.tld.label.ReservedList;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
|
||||
import google.registry.request.UrlConnectionService;
|
||||
import google.registry.server.Route;
|
||||
import google.registry.server.TestServer;
|
||||
import google.registry.testing.FakeClock;
|
||||
import google.registry.testing.FakeResponse;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.annotation.MultipartConfig;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.Part;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.InetAddress;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -102,13 +129,112 @@ public class UploadBsaUnavailableDomainsActionTest {
|
||||
BlobId existingFile =
|
||||
BlobId.of(BUCKET, String.format("unavailable_domains_%s.txt", clock.nowUtc()));
|
||||
String blockList = new String(gcsUtils.readBytesFrom(existingFile), UTF_8);
|
||||
assertThat(blockList).isEqualTo("ace.tld\nflagrant.tld\nfoobar.tld\njimmy.tld\ntine.tld");
|
||||
assertThat(blockList).isEqualTo("ace.tld\nflagrant.tld\nfoobar.tld\njimmy.tld\ntine.tld\n");
|
||||
assertThat(blockList).doesNotContain("not-blocked.tld");
|
||||
|
||||
// This test currently fails in the upload-to-bsa step.
|
||||
verify(emailSender, times(1))
|
||||
.sendNotification("BSA daily upload completed with errors", "Please see logs for details.");
|
||||
}
|
||||
|
||||
// TODO(mcilwain): Add test of BSA API upload as well.
|
||||
@Test
|
||||
void uploadToBsaTest() throws Exception {
|
||||
TestLogHandler logHandler = new TestLogHandler();
|
||||
Logger loggerToIntercept =
|
||||
Logger.getLogger(UploadBsaUnavailableDomainsAction.class.getCanonicalName());
|
||||
loggerToIntercept.addHandler(logHandler);
|
||||
|
||||
persistActiveDomain("foobar.tld");
|
||||
persistActiveDomain("ace.tld");
|
||||
persistDeletedDomain("not-blocked.tld", clock.nowUtc().minusDays(1));
|
||||
|
||||
var testServer = startTestServer();
|
||||
action.apiUrl = testServer.getUrl("/upload").toURI().toString();
|
||||
try {
|
||||
action.run();
|
||||
} finally {
|
||||
testServer.stop();
|
||||
}
|
||||
String dataSent = "ace.tld\nflagrant.tld\nfoobar.tld\njimmy.tld\ntine.tld\n";
|
||||
String checkSum = Hashing.sha512().hashString(dataSent, UTF_8).toString();
|
||||
String expectedResponse =
|
||||
"Received response with code 200 from server: "
|
||||
+ String.format("Checksum: [%s]\n%s\n", checkSum, dataSent);
|
||||
assertAboutLogs().that(logHandler).hasLogAtLevelWithMessage(Level.INFO, expectedResponse);
|
||||
verify(emailSender, times(1)).sendNotification("BSA daily upload completed successfully", "");
|
||||
}
|
||||
|
||||
private TestServer startTestServer() throws Exception {
|
||||
TestServer testServer =
|
||||
new TestServer(
|
||||
HostAndPort.fromParts(InetAddress.getLocalHost().getHostAddress(), pickUnusedPort()),
|
||||
ImmutableMap.of(),
|
||||
ImmutableList.of(Route.route("/upload", Servelet.class)));
|
||||
testServer.start();
|
||||
newSingleThreadExecutor()
|
||||
.execute(
|
||||
() -> {
|
||||
try {
|
||||
while (true) {
|
||||
testServer.process();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
// Expected
|
||||
}
|
||||
});
|
||||
return testServer;
|
||||
}
|
||||
|
||||
@MultipartConfig(
|
||||
location = "", // Directory for storing uploaded files. Use default when blank
|
||||
maxFileSize = 10485760L, // 10MB
|
||||
maxRequestSize = 20971520L, // 20MB
|
||||
fileSizeThreshold = 1048576 // Save in memory if file size < 1MB
|
||||
)
|
||||
public static class Servelet extends HttpServlet {
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
String checkSum = null;
|
||||
String content = null;
|
||||
try {
|
||||
for (Part part : req.getParts()) {
|
||||
switch (part.getName()) {
|
||||
case "zone" -> checkSum = readChecksum(part);
|
||||
case "file" -> content = readGzipped(part);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.atInfo().withCause(e).log("");
|
||||
}
|
||||
int status = checkSum == null || content == null ? 400 : 200;
|
||||
resp.setStatus(status);
|
||||
resp.setContentType("text/plain");
|
||||
try (PrintWriter writer = resp.getWriter()) {
|
||||
writer.printf("Checksum: [%s]\n%s\n", checkSum, content);
|
||||
}
|
||||
}
|
||||
|
||||
private String readChecksum(Part part) {
|
||||
try (InputStream is = part.getInputStream()) {
|
||||
return new Gson()
|
||||
.fromJson(new String(ByteStreams.toByteArray(is), UTF_8), Map.class)
|
||||
.getOrDefault("checkSum", "Not found")
|
||||
.toString();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private String readGzipped(Part part) {
|
||||
try (InputStream is = part.getInputStream();
|
||||
GZIPInputStream gis = new GZIPInputStream(is)) {
|
||||
return new String(ByteStreams.toByteArray(gis), UTF_8);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,6 +182,43 @@ class ContactDeleteFlowTest extends ResourceFlowTestCase<ContactDeleteFlow, Cont
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_clientDeleteProhibited_superuser() throws Exception {
|
||||
persistResource(
|
||||
persistActiveContact(getUniqueIdFromCommand())
|
||||
.asBuilder()
|
||||
.addStatusValue(StatusValue.CLIENT_DELETE_PROHIBITED)
|
||||
.build());
|
||||
runFlowAssertResponse(
|
||||
CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("contact_delete_response.xml"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_serverDeleteProhibited_superuser() throws Exception {
|
||||
persistResource(
|
||||
persistActiveContact(getUniqueIdFromCommand())
|
||||
.asBuilder()
|
||||
.addStatusValue(StatusValue.SERVER_DELETE_PROHIBITED)
|
||||
.build());
|
||||
runFlowAssertResponse(
|
||||
CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("contact_delete_response.xml"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_pendingDelete_superuser() throws Exception {
|
||||
persistResource(
|
||||
persistActiveContact(getUniqueIdFromCommand())
|
||||
.asBuilder()
|
||||
.addStatusValue(StatusValue.PENDING_DELETE)
|
||||
.build());
|
||||
assertAboutEppExceptions()
|
||||
.that(
|
||||
assertThrows(
|
||||
ResourceStatusProhibitsOperationException.class,
|
||||
() -> runFlow(CommitMode.LIVE, UserPrivileges.SUPERUSER)))
|
||||
.marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_unauthorizedClient() throws Exception {
|
||||
sessionMetadata.setRegistrarId("NewRegistrar");
|
||||
|
||||
@@ -179,6 +179,7 @@ import google.registry.model.reporting.DomainTransactionRecord;
|
||||
import google.registry.model.reporting.DomainTransactionRecord.TransactionReportField;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.model.reporting.HistoryEntry.HistoryEntryId;
|
||||
import google.registry.model.smd.SignedMarkRevocationListDao;
|
||||
import google.registry.model.tld.Tld;
|
||||
import google.registry.model.tld.Tld.TldState;
|
||||
import google.registry.model.tld.Tld.TldType;
|
||||
@@ -2727,8 +2728,9 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
|
||||
@Test
|
||||
void testFail_startDateSunriseRegistration_revokedSignedMark() throws Exception {
|
||||
SmdrlCsvParser.parse(TmchTestData.loadFile("smd/smdrl.csv").lines().collect(toImmutableList()))
|
||||
.save();
|
||||
SignedMarkRevocationListDao.save(
|
||||
SmdrlCsvParser.parse(
|
||||
TmchTestData.loadFile("smd/smdrl.csv").lines().collect(toImmutableList())));
|
||||
createTld("tld", START_DATE_SUNRISE);
|
||||
clock.setTo(SMD_VALID_TIME);
|
||||
String revokedSmd =
|
||||
@@ -2753,9 +2755,9 @@ class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow, Domain
|
||||
if (labels.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
SmdrlCsvParser.parse(
|
||||
TmchTestData.loadFile("idn/idn_smdrl.csv").lines().collect(toImmutableList()))
|
||||
.save();
|
||||
SignedMarkRevocationListDao.save(
|
||||
SmdrlCsvParser.parse(
|
||||
TmchTestData.loadFile("idn/idn_smdrl.csv").lines().collect(toImmutableList())));
|
||||
createTld("tld", START_DATE_SUNRISE);
|
||||
clock.setTo(SMD_VALID_TIME);
|
||||
String revokedSmd =
|
||||
|
||||
@@ -917,6 +917,52 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
|
||||
assertThat(thrown).hasMessageThat().contains("pendingDelete");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_clientDeleteProhibited_superuser() throws Exception {
|
||||
eppRequestSource = EppRequestSource.TOOL;
|
||||
setEppInput(
|
||||
"domain_delete_superuser_extension.xml",
|
||||
ImmutableMap.of("REDEMPTION_GRACE_PERIOD_DAYS", "15", "PENDING_DELETE_DAYS", "0"));
|
||||
setUpSuccessfulTest();
|
||||
|
||||
persistResource(
|
||||
domain.asBuilder().addStatusValue(StatusValue.CLIENT_DELETE_PROHIBITED).build());
|
||||
clock.advanceOneMilli();
|
||||
runFlowAssertResponse(
|
||||
CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("domain_delete_response_pending.xml"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_serverDeleteProhibited_superuser() throws Exception {
|
||||
eppRequestSource = EppRequestSource.TOOL;
|
||||
setEppInput(
|
||||
"domain_delete_superuser_extension.xml",
|
||||
ImmutableMap.of("REDEMPTION_GRACE_PERIOD_DAYS", "15", "PENDING_DELETE_DAYS", "0"));
|
||||
setUpSuccessfulTest();
|
||||
|
||||
persistResource(
|
||||
domain.asBuilder().addStatusValue(StatusValue.SERVER_DELETE_PROHIBITED).build());
|
||||
clock.advanceOneMilli();
|
||||
runFlowAssertResponse(
|
||||
CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("domain_delete_response_pending.xml"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_pendingDelete_superuser() throws Exception {
|
||||
eppRequestSource = EppRequestSource.TOOL;
|
||||
setEppInput(
|
||||
"domain_delete_superuser_extension.xml",
|
||||
ImmutableMap.of("REDEMPTION_GRACE_PERIOD_DAYS", "15", "PENDING_DELETE_DAYS", "0"));
|
||||
setUpSuccessfulTest();
|
||||
persistResource(domain.asBuilder().addStatusValue(StatusValue.PENDING_DELETE).build());
|
||||
|
||||
ResourceStatusProhibitsOperationException thrown =
|
||||
assertThrows(
|
||||
ResourceStatusProhibitsOperationException.class,
|
||||
() -> runFlow(CommitMode.LIVE, UserPrivileges.SUPERUSER));
|
||||
assertThat(thrown).hasMessageThat().contains("pendingDelete");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_metadata() throws Exception {
|
||||
eppRequestSource = EppRequestSource.TOOL;
|
||||
|
||||
@@ -346,18 +346,18 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_minimumDatasetPhase2_nonRegistrantContactsStillExist() throws Exception {
|
||||
void testFailure_minimumDatasetPhase2_whenAddingNewContacts() throws Exception {
|
||||
persistResource(
|
||||
new FeatureFlag.Builder()
|
||||
.setFeatureName(MINIMUM_DATASET_CONTACTS_PROHIBITED)
|
||||
.setStatusMap(
|
||||
ImmutableSortedMap.of(START_OF_TIME, INACTIVE, clock.nowUtc().minusDays(5), ACTIVE))
|
||||
.build());
|
||||
// This EPP adds a new technical contact mak21 that wasn't already present.
|
||||
setEppInput("domain_update_empty_registrant.xml");
|
||||
persistReferencedEntities();
|
||||
persistDomain();
|
||||
// Fails because after the update the domain would still have some contacts on it even though
|
||||
// the registrant has been removed.
|
||||
// Fails because the update adds some new contacts, although the registrant has been removed.
|
||||
ContactsProhibitedException thrown =
|
||||
assertThrows(ContactsProhibitedException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
@@ -1574,14 +1574,13 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_minimumDatasetPhase2_registrantStillExists() throws Exception {
|
||||
void testFailure_minimumDatasetPhase2_addingNewRegistrantFails() throws Exception {
|
||||
persistResource(
|
||||
new FeatureFlag.Builder()
|
||||
.setFeatureName(MINIMUM_DATASET_CONTACTS_PROHIBITED)
|
||||
.setStatusMap(
|
||||
ImmutableSortedMap.of(START_OF_TIME, INACTIVE, clock.nowUtc().minusDays(5), ACTIVE))
|
||||
.build());
|
||||
setEppInput("domain_update_remove_admin.xml");
|
||||
persistReferencedEntities();
|
||||
persistResource(
|
||||
DatabaseHelper.newDomain(getUniqueIdFromCommand())
|
||||
@@ -1590,7 +1589,10 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
|
||||
ImmutableSet.of(
|
||||
DesignatedContact.create(Type.ADMIN, sh8013Contact.createVKey()),
|
||||
DesignatedContact.create(Type.TECH, sh8013Contact.createVKey())))
|
||||
.setRegistrant(Optional.empty())
|
||||
.build());
|
||||
// This EPP sets the registrant to sh8013, whereas in our test setup it is absent.
|
||||
setEppInput("domain_update_registrant.xml");
|
||||
RegistrantProhibitedException thrown =
|
||||
assertThrows(RegistrantProhibitedException.class, this::runFlow);
|
||||
assertAboutEppExceptions().that(thrown).marshalsToXml();
|
||||
@@ -1657,6 +1659,32 @@ class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow, Domain
|
||||
assertThat(updatedDomain.getContacts()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_minimumDatasetPhase2_removeOneContact() throws Exception {
|
||||
persistResource(
|
||||
new FeatureFlag.Builder()
|
||||
.setFeatureName(MINIMUM_DATASET_CONTACTS_PROHIBITED)
|
||||
.setStatusMap(
|
||||
ImmutableSortedMap.of(START_OF_TIME, INACTIVE, clock.nowUtc().minusDays(5), ACTIVE))
|
||||
.build());
|
||||
setEppInput("domain_update_remove_admin.xml");
|
||||
persistReferencedEntities();
|
||||
persistResource(
|
||||
DatabaseHelper.newDomain(getUniqueIdFromCommand())
|
||||
.asBuilder()
|
||||
.setContacts(
|
||||
ImmutableSet.of(
|
||||
DesignatedContact.create(Type.ADMIN, sh8013Contact.createVKey()),
|
||||
DesignatedContact.create(Type.TECH, sh8013Contact.createVKey())))
|
||||
.build());
|
||||
assertThat(reloadResourceByForeignKey().getRegistrant()).isPresent();
|
||||
assertThat(reloadResourceByForeignKey().getContacts()).hasSize(2);
|
||||
runFlowAssertResponse(loadFile("generic_success_response.xml"));
|
||||
Domain updatedDomain = reloadResourceByForeignKey();
|
||||
assertThat(updatedDomain.getRegistrant()).isPresent();
|
||||
assertThat(updatedDomain.getContacts()).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_addPendingDeleteContact() throws Exception {
|
||||
persistReferencedEntities();
|
||||
|
||||
@@ -153,6 +153,43 @@ class HostDeleteFlowTest extends ResourceFlowTestCase<HostDeleteFlow, Host> {
|
||||
assertSqlDeleteSuccess();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_clientDeleteProhibited_superuser() throws Exception {
|
||||
persistResource(
|
||||
persistActiveHost("ns1.example.tld")
|
||||
.asBuilder()
|
||||
.addStatusValue(StatusValue.CLIENT_DELETE_PROHIBITED)
|
||||
.build());
|
||||
runFlowAssertResponse(
|
||||
CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("host_delete_response.xml"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_serverDeleteProhibited_superuser() throws Exception {
|
||||
persistResource(
|
||||
persistActiveHost("ns1.example.tld")
|
||||
.asBuilder()
|
||||
.addStatusValue(StatusValue.SERVER_DELETE_PROHIBITED)
|
||||
.build());
|
||||
runFlowAssertResponse(
|
||||
CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("host_delete_response.xml"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_pendingDelete_superuser() throws Exception {
|
||||
persistResource(
|
||||
persistActiveHost("ns1.example.tld")
|
||||
.asBuilder()
|
||||
.addStatusValue(StatusValue.PENDING_DELETE)
|
||||
.build());
|
||||
assertAboutEppExceptions()
|
||||
.that(
|
||||
assertThrows(
|
||||
ResourceStatusProhibitsOperationException.class,
|
||||
() -> runFlow(CommitMode.LIVE, UserPrivileges.SUPERUSER)))
|
||||
.marshalsToXml();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_authorizedClientReadFromSuperordinate() throws Exception {
|
||||
sessionMetadata.setRegistrarId("TheRegistrar");
|
||||
|
||||
@@ -341,11 +341,10 @@ class RegistrarTest extends EntityTestCase {
|
||||
.setTypes(ImmutableSet.of(RegistrarPoc.Type.TECH, RegistrarPoc.Type.ABUSE))
|
||||
.build());
|
||||
abuseAdminContact = DatabaseHelper.loadByKey(abuseAdminContact.createVKey());
|
||||
ImmutableSortedSet<RegistrarPoc> techContacts =
|
||||
registrar.getContactsOfType(RegistrarPoc.Type.TECH);
|
||||
ImmutableSortedSet<RegistrarPoc> techContacts = registrar.getPocsOfType(RegistrarPoc.Type.TECH);
|
||||
assertThat(techContacts).containsExactly(newTechContact, newTechAbuseContact).inOrder();
|
||||
ImmutableSortedSet<RegistrarPoc> abuseContacts =
|
||||
registrar.getContactsOfType(RegistrarPoc.Type.ABUSE);
|
||||
registrar.getPocsOfType(RegistrarPoc.Type.ABUSE);
|
||||
assertThat(abuseContacts).containsExactly(newTechAbuseContact, abuseAdminContact).inOrder();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,9 +16,12 @@ package google.registry.model.smd;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import google.registry.model.EntityTestCase;
|
||||
import jakarta.persistence.OptimisticLockException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class SignedMarkRevocationListDaoTest extends EntityTestCase {
|
||||
@@ -32,11 +35,29 @@ public class SignedMarkRevocationListDaoTest extends EntityTestCase {
|
||||
SignedMarkRevocationList list =
|
||||
SignedMarkRevocationList.create(
|
||||
fakeClock.nowUtc(), ImmutableMap.of("mark", fakeClock.nowUtc().minusHours(1)));
|
||||
SignedMarkRevocationListDao.save(list);
|
||||
list = SignedMarkRevocationListDao.save(list);
|
||||
SignedMarkRevocationList fromDb = SignedMarkRevocationListDao.load();
|
||||
assertAboutImmutableObjects().that(fromDb).isEqualExceptFields(list);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSave_retrySuccess() {
|
||||
SignedMarkRevocationList list =
|
||||
SignedMarkRevocationList.create(
|
||||
fakeClock.nowUtc(), ImmutableMap.of("mark", fakeClock.nowUtc().minusHours(1)));
|
||||
AtomicBoolean isFirstAttempt = new AtomicBoolean(true);
|
||||
tm().transact(
|
||||
() -> {
|
||||
SignedMarkRevocationListDao.save(list);
|
||||
if (isFirstAttempt.get()) {
|
||||
isFirstAttempt.set(false);
|
||||
throw new OptimisticLockException();
|
||||
}
|
||||
});
|
||||
SignedMarkRevocationList fromDb = SignedMarkRevocationListDao.load();
|
||||
assertAboutImmutableObjects().that(fromDb).isEqualExceptFields(list, "revisionId");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSaveAndLoad_emptyList() {
|
||||
SignedMarkRevocationList list =
|
||||
|
||||
@@ -48,7 +48,8 @@ public class SignedMarkRevocationListTest {
|
||||
for (int i = 0; i < rows; i++) {
|
||||
revokes.put(Integer.toString(i), clock.nowUtc());
|
||||
}
|
||||
SignedMarkRevocationList.create(clock.nowUtc(), revokes.build()).save();
|
||||
SignedMarkRevocationListDao.save(
|
||||
SignedMarkRevocationList.create(clock.nowUtc(), revokes.build()));
|
||||
SignedMarkRevocationList res = SignedMarkRevocationList.get();
|
||||
assertThat(res.size()).isEqualTo(rows);
|
||||
return res;
|
||||
|
||||
@@ -31,10 +31,12 @@ import google.registry.persistence.transaction.JpaTestExtensions;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension;
|
||||
import google.registry.testing.FakeClock;
|
||||
import google.registry.testing.TestCacheExtension;
|
||||
import jakarta.persistence.OptimisticLockException;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Duration;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.IntStream;
|
||||
import org.joda.money.CurrencyUnit;
|
||||
import org.joda.money.Money;
|
||||
@@ -93,6 +95,27 @@ public class PremiumListDaoTest {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void saveNew_retry_success() {
|
||||
AtomicBoolean isFirstAttempt = new AtomicBoolean(true);
|
||||
tm().transact(
|
||||
() -> {
|
||||
PremiumListDao.save(testList);
|
||||
if (isFirstAttempt.get()) {
|
||||
isFirstAttempt.set(false);
|
||||
throw new OptimisticLockException();
|
||||
}
|
||||
});
|
||||
tm().transact(
|
||||
() -> {
|
||||
Optional<PremiumList> persistedListOpt = PremiumListDao.getLatestRevision("testname");
|
||||
assertThat(persistedListOpt).isPresent();
|
||||
PremiumList persistedList = persistedListOpt.get();
|
||||
assertThat(persistedList.getLabelsToPrices()).containsExactlyEntriesIn(TEST_PRICES);
|
||||
assertThat(persistedList.getCreationTimestamp()).isEqualTo(fakeClock.nowUtc());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void update_worksSuccessfully() {
|
||||
PremiumListDao.save(testList);
|
||||
|
||||
@@ -22,6 +22,8 @@ import google.registry.model.tld.label.ReservedList.ReservedListEntry;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension;
|
||||
import google.registry.testing.FakeClock;
|
||||
import jakarta.persistence.OptimisticLockException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
@@ -71,11 +73,34 @@ public class ReservedListDaoTest {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void save_withRetry_worksSuccessfully() {
|
||||
AtomicBoolean isFirstAttempt = new AtomicBoolean(true);
|
||||
tm().transact(
|
||||
() -> {
|
||||
ReservedListDao.save(testReservedList);
|
||||
if (isFirstAttempt.get()) {
|
||||
isFirstAttempt.set(false);
|
||||
throw new OptimisticLockException();
|
||||
}
|
||||
});
|
||||
tm().transact(
|
||||
() -> {
|
||||
ReservedList persistedList =
|
||||
tm().query("FROM ReservedList WHERE name = :name", ReservedList.class)
|
||||
.setParameter("name", "testlist")
|
||||
.getSingleResult();
|
||||
assertThat(persistedList.getReservedListEntries())
|
||||
.containsExactlyEntriesIn(testReservations);
|
||||
assertThat(persistedList.getCreationTimestamp()).isEqualTo(fakeClock.nowUtc());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void delete_worksSuccessfully() {
|
||||
ReservedListDao.save(testReservedList);
|
||||
var persisted = ReservedListDao.save(testReservedList);
|
||||
assertThat(ReservedListDao.checkExists("testlist")).isTrue();
|
||||
ReservedListDao.delete(testReservedList);
|
||||
ReservedListDao.delete(persisted);
|
||||
assertThat(ReservedListDao.checkExists("testlist")).isFalse();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,15 +16,15 @@ package google.registry.model.tmch;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension;
|
||||
import google.registry.testing.FakeClock;
|
||||
import google.registry.testing.TestCacheExtension;
|
||||
import jakarta.persistence.PersistenceException;
|
||||
import jakarta.persistence.OptimisticLockException;
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
@@ -49,27 +49,36 @@ public class ClaimsListDaoTest {
|
||||
void save_insertsClaimsListSuccessfully() {
|
||||
ClaimsList claimsList =
|
||||
ClaimsList.create(fakeClock.nowUtc(), ImmutableMap.of("label1", "key1", "label2", "key2"));
|
||||
ClaimsListDao.save(claimsList);
|
||||
claimsList = ClaimsListDao.save(claimsList);
|
||||
ClaimsList insertedClaimsList = ClaimsListDao.get();
|
||||
assertClaimsListEquals(claimsList, insertedClaimsList);
|
||||
assertThat(insertedClaimsList.getCreationTimestamp()).isEqualTo(fakeClock.nowUtc());
|
||||
}
|
||||
|
||||
@Test
|
||||
void save_fail_duplicateId() {
|
||||
void save_insertsClaimsListSuccessfully_withRetries() {
|
||||
ClaimsList claimsList =
|
||||
ClaimsList.create(fakeClock.nowUtc(), ImmutableMap.of("label1", "key1", "label2", "key2"));
|
||||
ClaimsListDao.save(claimsList);
|
||||
AtomicBoolean isFirstAttempt = new AtomicBoolean(true);
|
||||
tm().transact(
|
||||
() -> {
|
||||
ClaimsListDao.save(claimsList);
|
||||
if (isFirstAttempt.get()) {
|
||||
isFirstAttempt.set(false);
|
||||
throw new OptimisticLockException();
|
||||
}
|
||||
});
|
||||
ClaimsList insertedClaimsList = ClaimsListDao.get();
|
||||
assertClaimsListEquals(claimsList, insertedClaimsList);
|
||||
// Save ClaimsList with existing revisionId should fail because revisionId is the primary key.
|
||||
assertThrows(PersistenceException.class, () -> ClaimsListDao.save(insertedClaimsList));
|
||||
assertThat(insertedClaimsList.getTmdbGenerationTime())
|
||||
.isEqualTo(claimsList.getTmdbGenerationTime());
|
||||
assertThat(insertedClaimsList.getLabelsToKeys()).isEqualTo(claimsList.getLabelsToKeys());
|
||||
assertThat(insertedClaimsList.getCreationTimestamp()).isEqualTo(fakeClock.nowUtc());
|
||||
}
|
||||
|
||||
@Test
|
||||
void save_claimsListWithNoEntries() {
|
||||
ClaimsList claimsList = ClaimsList.create(fakeClock.nowUtc(), ImmutableMap.of());
|
||||
ClaimsListDao.save(claimsList);
|
||||
claimsList = ClaimsListDao.save(claimsList);
|
||||
ClaimsList insertedClaimsList = ClaimsListDao.get();
|
||||
assertClaimsListEquals(claimsList, insertedClaimsList);
|
||||
assertThat(insertedClaimsList.getLabelsToKeys()).isEmpty();
|
||||
@@ -86,8 +95,8 @@ public class ClaimsListDaoTest {
|
||||
ClaimsList.create(fakeClock.nowUtc(), ImmutableMap.of("label1", "key1", "label2", "key2"));
|
||||
ClaimsList newClaimsList =
|
||||
ClaimsList.create(fakeClock.nowUtc(), ImmutableMap.of("label3", "key3", "label4", "key4"));
|
||||
ClaimsListDao.save(oldClaimsList);
|
||||
ClaimsListDao.save(newClaimsList);
|
||||
oldClaimsList = ClaimsListDao.save(oldClaimsList);
|
||||
newClaimsList = ClaimsListDao.save(newClaimsList);
|
||||
assertClaimsListEquals(newClaimsList, ClaimsListDao.get());
|
||||
}
|
||||
|
||||
@@ -96,11 +105,11 @@ public class ClaimsListDaoTest {
|
||||
assertThat(ClaimsListDao.CACHE.getIfPresent(ClaimsListDao.class)).isNull();
|
||||
ClaimsList oldList =
|
||||
ClaimsList.create(fakeClock.nowUtc(), ImmutableMap.of("label1", "key1", "label2", "key2"));
|
||||
ClaimsListDao.save(oldList);
|
||||
oldList = ClaimsListDao.save(oldList);
|
||||
assertThat(ClaimsListDao.CACHE.getIfPresent(ClaimsListDao.class)).isEqualTo(oldList);
|
||||
ClaimsList newList =
|
||||
ClaimsList.create(fakeClock.nowUtc(), ImmutableMap.of("label3", "key3", "label4", "key4"));
|
||||
ClaimsListDao.save(newList);
|
||||
newList = ClaimsListDao.save(newList);
|
||||
assertThat(ClaimsListDao.CACHE.getIfPresent(ClaimsListDao.class)).isEqualTo(newList);
|
||||
}
|
||||
|
||||
|
||||
@@ -319,27 +319,6 @@ have failed to comply with these terms.",
|
||||
return putNext("REGISTRAR_HANDLE_", handle, "STATUS_", status);
|
||||
}
|
||||
|
||||
JsonFileBuilder addContact(String handle) {
|
||||
return putNext("CONTACT_HANDLE_", handle);
|
||||
}
|
||||
|
||||
JsonFileBuilder addFullContact(
|
||||
String handle,
|
||||
@Nullable String status,
|
||||
@Nullable String fullName,
|
||||
@Nullable String address) {
|
||||
if (fullName != null) {
|
||||
putNext("CONTACT_FULLNAME_", fullName);
|
||||
}
|
||||
if (address != null) {
|
||||
putNext("CONTACT_ADDRESS_", address);
|
||||
}
|
||||
if (status != null) {
|
||||
putNext("STATUS_", status);
|
||||
}
|
||||
return putNext("CONTACT_HANDLE_", handle);
|
||||
}
|
||||
|
||||
JsonFileBuilder setNextQuery(String nextQuery) {
|
||||
return put("NEXT_QUERY", nextQuery);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ package google.registry.rdap;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.bsa.persistence.BsaTestingUtils.persistBsaLabel;
|
||||
import static google.registry.model.EppResourceUtils.loadByForeignKey;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
|
||||
import static google.registry.testing.DatabaseHelper.persistDomainWithDependentResources;
|
||||
@@ -35,7 +34,6 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.gson.JsonObject;
|
||||
import google.registry.model.contact.Contact;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.domain.GracePeriod;
|
||||
import google.registry.model.domain.Period;
|
||||
@@ -50,65 +48,35 @@ import google.registry.rdap.RdapMetrics.SearchType;
|
||||
import google.registry.rdap.RdapMetrics.WildcardType;
|
||||
import google.registry.rdap.RdapSearchResults.IncompletenessWarningType;
|
||||
import google.registry.request.Action;
|
||||
import google.registry.testing.FullFieldsTestEntityHelper;
|
||||
import java.util.Optional;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link RdapDomainAction}.
|
||||
*
|
||||
* <p>TODO(b/26872828): The next time we do any work on RDAP, consider adding the APNIC RDAP
|
||||
* conformance checker to the unit test suite.
|
||||
*/
|
||||
/** Unit tests for {@link RdapDomainAction}. */
|
||||
class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
|
||||
RdapDomainActionTest() {
|
||||
super(RdapDomainAction.class);
|
||||
}
|
||||
|
||||
private Contact registrantLol;
|
||||
private Host host1;
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
// lol
|
||||
createTld("lol");
|
||||
Registrar registrarLol = persistResource(makeRegistrar(
|
||||
"evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE));
|
||||
Registrar registrarLol =
|
||||
persistResource(
|
||||
makeRegistrar("evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE));
|
||||
persistResources(makeRegistrarPocs(registrarLol));
|
||||
registrantLol =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"5372808-ERL",
|
||||
"Goblin Market",
|
||||
"lol@cat.lol",
|
||||
clock.nowUtc().minusYears(1),
|
||||
registrarLol);
|
||||
Contact adminContactLol =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"5372808-IRL",
|
||||
"Santa Claus",
|
||||
"BOFH@cat.lol",
|
||||
clock.nowUtc().minusYears(2),
|
||||
registrarLol);
|
||||
Contact techContactLol =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"5372808-TRL", "The Raven", "bog@cat.lol", clock.nowUtc().minusYears(3), registrarLol);
|
||||
host1 = makeAndPersistHost("ns1.cat.lol", "1.2.3.4", null, clock.nowUtc().minusYears(1));
|
||||
Host host2 =
|
||||
makeAndPersistHost(
|
||||
"ns2.cat.lol", "bad:f00d:cafe:0:0:0:15:beef", clock.nowUtc().minusYears(2));
|
||||
persistResource(
|
||||
makeDomain(
|
||||
"cat.lol",
|
||||
registrantLol,
|
||||
adminContactLol,
|
||||
techContactLol,
|
||||
host1,
|
||||
host2,
|
||||
registrarLol)
|
||||
makeDomain("cat.lol", null, null, null, host1, host2, registrarLol)
|
||||
.asBuilder()
|
||||
.setCreationTimeForTest(clock.nowUtc().minusYears(3))
|
||||
.setCreationRegistrarId("TheRegistrar")
|
||||
@@ -120,29 +88,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
"ns2.dodo.lol", "bad:f00d:cafe:0:0:0:15:beef", clock.nowUtc().minusYears(2));
|
||||
Domain domainDeleted =
|
||||
persistResource(
|
||||
makeDomain(
|
||||
"dodo.lol",
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"5372808-ERL",
|
||||
"Goblin Market",
|
||||
"lol@cat.lol",
|
||||
clock.nowUtc().minusYears(1),
|
||||
registrarLol),
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"5372808-IRL",
|
||||
"Santa Claus",
|
||||
"BOFH@cat.lol",
|
||||
clock.nowUtc().minusYears(2),
|
||||
registrarLol),
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"5372808-TRL",
|
||||
"The Raven",
|
||||
"bog@cat.lol",
|
||||
clock.nowUtc().minusYears(3),
|
||||
registrarLol),
|
||||
host1,
|
||||
hostDodo2,
|
||||
registrarLol)
|
||||
makeDomain("dodo.lol", null, null, null, host1, hostDodo2, registrarLol)
|
||||
.asBuilder()
|
||||
.setCreationTimeForTest(clock.nowUtc().minusYears(3))
|
||||
.setCreationRegistrarId("TheRegistrar")
|
||||
@@ -153,32 +99,8 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
Registrar registrarIdn =
|
||||
persistResource(makeRegistrar("idnregistrar", "IDN Registrar", Registrar.State.ACTIVE));
|
||||
persistResources(makeRegistrarPocs(registrarIdn));
|
||||
Contact registrantIdn =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"5372808-ERL",
|
||||
"Goblin Market",
|
||||
"lol@cat.lol",
|
||||
clock.nowUtc().minusYears(1),
|
||||
registrarIdn);
|
||||
Contact adminContactIdn =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"5372808-IRL",
|
||||
"Santa Claus",
|
||||
"BOFH@cat.lol",
|
||||
clock.nowUtc().minusYears(2),
|
||||
registrarIdn);
|
||||
Contact techContactIdn =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"5372808-TRL", "The Raven", "bog@cat.lol", clock.nowUtc().minusYears(3), registrarIdn);
|
||||
persistResource(
|
||||
makeDomain(
|
||||
"cat.みんな",
|
||||
registrantIdn,
|
||||
adminContactIdn,
|
||||
techContactIdn,
|
||||
host1,
|
||||
host2,
|
||||
registrarIdn)
|
||||
makeDomain("cat.みんな", null, null, null, host1, host2, registrarIdn)
|
||||
.asBuilder()
|
||||
.setCreationTimeForTest(clock.nowUtc().minusYears(3))
|
||||
.setCreationRegistrarId("TheRegistrar")
|
||||
@@ -186,35 +108,12 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
|
||||
// 1.tld
|
||||
createTld("1.tld");
|
||||
Registrar registrar1Tld = persistResource(
|
||||
makeRegistrar("1tldregistrar", "Multilevel Registrar", Registrar.State.ACTIVE));
|
||||
Registrar registrar1Tld =
|
||||
persistResource(
|
||||
makeRegistrar("1tldregistrar", "Multilevel Registrar", Registrar.State.ACTIVE));
|
||||
persistResources(makeRegistrarPocs(registrar1Tld));
|
||||
Contact registrant1Tld =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"5372808-ERL",
|
||||
"Goblin Market",
|
||||
"lol@cat.lol",
|
||||
clock.nowUtc().minusYears(1),
|
||||
registrar1Tld);
|
||||
Contact adminContact1Tld =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"5372808-IRL",
|
||||
"Santa Claus",
|
||||
"BOFH@cat.lol",
|
||||
clock.nowUtc().minusYears(2),
|
||||
registrar1Tld);
|
||||
Contact techContact1Tld =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"5372808-TRL", "The Raven", "bog@cat.lol", clock.nowUtc().minusYears(3), registrar1Tld);
|
||||
persistResource(
|
||||
makeDomain(
|
||||
"cat.1.tld",
|
||||
registrant1Tld,
|
||||
adminContact1Tld,
|
||||
techContact1Tld,
|
||||
host1,
|
||||
host2,
|
||||
registrar1Tld)
|
||||
makeDomain("cat.1.tld", null, null, null, host1, host2, registrar1Tld)
|
||||
.asBuilder()
|
||||
.setCreationTimeForTest(clock.nowUtc().minusYears(3))
|
||||
.setCreationRegistrarId("TheRegistrar")
|
||||
@@ -236,12 +135,9 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
.isEqualTo(
|
||||
addDomainBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.lol", "C-LOL")
|
||||
.addContact("4-ROID")
|
||||
.addContact("6-ROID")
|
||||
.addContact("2-ROID")
|
||||
.addNameserver("ns1.cat.lol", "8-ROID")
|
||||
.addNameserver("ns2.cat.lol", "A-ROID")
|
||||
.addDomain("cat.lol", "6-LOL")
|
||||
.addNameserver("ns1.cat.lol", "2-ROID")
|
||||
.addNameserver("ns2.cat.lol", "4-ROID")
|
||||
.addRegistrar("Yes Virginia <script>")
|
||||
.load(expectedOutputFile)));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
@@ -260,15 +156,11 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUnknownDomain_returns400() {
|
||||
void testUnknownDomain_returns404() {
|
||||
assertAboutJson()
|
||||
.that(generateActualJson("missingdomain.com"))
|
||||
.isEqualTo(
|
||||
generateExpectedJsonError(
|
||||
"missingdomain.com is not a valid domain name: Domain name is under tld com which"
|
||||
+ " doesn't exist",
|
||||
400));
|
||||
assertThat(response.getStatus()).isEqualTo(400);
|
||||
.isEqualTo(generateExpectedJsonError("missingdomain.com not found", 404));
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -283,67 +175,19 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
assertProperResponseForCatLol("cat.lol", "rdap_domain.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidDomain_notLoggedIn_redactsAllContactInfo() {
|
||||
assertProperResponseForCatLol("cat.lol", "rdap_domain_redacted_contacts_with_remark.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidDomain_notLoggedIn_showsNoRegistrant_whenRegistrantDoesntExist() {
|
||||
persistResource(
|
||||
loadByForeignKey(Domain.class, "cat.lol", clock.nowUtc())
|
||||
.get()
|
||||
.asBuilder()
|
||||
.setRegistrant(Optional.empty())
|
||||
.build());
|
||||
assertProperResponseForCatLol("cat.lol", "rdap_domain_no_registrant_with_remark.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidDomain_notLoggedIn_containsNoContactEntities_whenNoContactsExist() {
|
||||
persistResource(
|
||||
loadByForeignKey(Domain.class, "cat.lol", clock.nowUtc())
|
||||
.get()
|
||||
.asBuilder()
|
||||
.setRegistrant(Optional.empty())
|
||||
.setContacts(ImmutableSet.of())
|
||||
.build());
|
||||
assertProperResponseForCatLol("cat.lol", "rdap_domain_no_contacts_exist_with_remark.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidDomain_loggedIn_containsNoContactEntities_whenNoContactsExist() {
|
||||
login("evilregistrar");
|
||||
persistResource(
|
||||
loadByForeignKey(Domain.class, "cat.lol", clock.nowUtc())
|
||||
.get()
|
||||
.asBuilder()
|
||||
.setRegistrant(Optional.empty())
|
||||
.setContacts(ImmutableSet.of())
|
||||
.build());
|
||||
assertProperResponseForCatLol("cat.lol", "rdap_domain_no_contacts_exist_with_remark.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidDomain_loggedInAsOtherRegistrar_redactsAllContactInfo() {
|
||||
login("idnregistrar");
|
||||
assertProperResponseForCatLol("cat.lol", "rdap_domain_redacted_contacts_with_remark.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpperCase_ignored() {
|
||||
assertProperResponseForCatLol("CaT.lOl", "rdap_domain_redacted_contacts_with_remark.json");
|
||||
assertProperResponseForCatLol("CaT.lOl", "rdap_domain.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTrailingDot_ignored() {
|
||||
assertProperResponseForCatLol("cat.lol.", "rdap_domain_redacted_contacts_with_remark.json");
|
||||
assertProperResponseForCatLol("cat.lol.", "rdap_domain.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testQueryParameter_ignored() {
|
||||
assertProperResponseForCatLol(
|
||||
"cat.lol?key=value", "rdap_domain_redacted_contacts_with_remark.json");
|
||||
assertProperResponseForCatLol("cat.lol?key=value", "rdap_domain.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -354,12 +198,9 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
.isEqualTo(
|
||||
addDomainBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.みんな", "1D-Q9JYB4C")
|
||||
.addContact("19-ROID")
|
||||
.addContact("1B-ROID")
|
||||
.addContact("17-ROID")
|
||||
.addNameserver("ns1.cat.lol", "8-ROID")
|
||||
.addNameserver("ns2.cat.lol", "A-ROID")
|
||||
.addDomain("cat.みんな", "B-Q9JYB4C")
|
||||
.addNameserver("ns1.cat.lol", "2-ROID")
|
||||
.addNameserver("ns2.cat.lol", "4-ROID")
|
||||
.addRegistrar("IDN Registrar")
|
||||
.load("rdap_domain_unicode.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
@@ -373,12 +214,9 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
.isEqualTo(
|
||||
addDomainBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.みんな", "1D-Q9JYB4C")
|
||||
.addContact("19-ROID")
|
||||
.addContact("1B-ROID")
|
||||
.addContact("17-ROID")
|
||||
.addNameserver("ns1.cat.lol", "8-ROID")
|
||||
.addNameserver("ns2.cat.lol", "A-ROID")
|
||||
.addDomain("cat.みんな", "B-Q9JYB4C")
|
||||
.addNameserver("ns1.cat.lol", "2-ROID")
|
||||
.addNameserver("ns2.cat.lol", "4-ROID")
|
||||
.addRegistrar("IDN Registrar")
|
||||
.load("rdap_domain_unicode.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
@@ -392,12 +230,9 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
.isEqualTo(
|
||||
addDomainBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.みんな", "1D-Q9JYB4C")
|
||||
.addContact("19-ROID")
|
||||
.addContact("1B-ROID")
|
||||
.addContact("17-ROID")
|
||||
.addNameserver("ns1.cat.lol", "8-ROID")
|
||||
.addNameserver("ns2.cat.lol", "A-ROID")
|
||||
.addDomain("cat.みんな", "B-Q9JYB4C")
|
||||
.addNameserver("ns1.cat.lol", "2-ROID")
|
||||
.addNameserver("ns2.cat.lol", "4-ROID")
|
||||
.addRegistrar("IDN Registrar")
|
||||
.load("rdap_domain_unicode.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
@@ -411,12 +246,9 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
.isEqualTo(
|
||||
addDomainBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.1.tld", "25-1_TLD")
|
||||
.addContact("21-ROID")
|
||||
.addContact("23-ROID")
|
||||
.addContact("1F-ROID")
|
||||
.addNameserver("ns1.cat.lol", "8-ROID")
|
||||
.addNameserver("ns2.cat.lol", "A-ROID")
|
||||
.addDomain("cat.1.tld", "D-1_TLD")
|
||||
.addNameserver("ns1.cat.lol", "2-ROID")
|
||||
.addNameserver("ns2.cat.lol", "4-ROID")
|
||||
.addRegistrar("Multilevel Registrar")
|
||||
.load("rdap_domain.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
@@ -470,12 +302,9 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
.isEqualTo(
|
||||
addDomainBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addDomain("dodo.lol", "15-LOL")
|
||||
.addContact("11-ROID")
|
||||
.addContact("13-ROID")
|
||||
.addContact("F-ROID")
|
||||
.addNameserver("ns1.cat.lol", "8-ROID")
|
||||
.addNameserver("ns2.dodo.lol", "D-ROID")
|
||||
.addDomain("dodo.lol", "9-LOL")
|
||||
.addNameserver("ns1.cat.lol", "2-ROID")
|
||||
.addNameserver("ns2.dodo.lol", "7-ROID")
|
||||
.addRegistrar("Yes Virginia <script>")
|
||||
.load("rdap_domain_deleted.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
@@ -490,12 +319,9 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
.isEqualTo(
|
||||
addDomainBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addDomain("dodo.lol", "15-LOL")
|
||||
.addContact("11-ROID")
|
||||
.addContact("13-ROID")
|
||||
.addContact("F-ROID")
|
||||
.addNameserver("ns1.cat.lol", "8-ROID")
|
||||
.addNameserver("ns2.dodo.lol", "D-ROID")
|
||||
.addDomain("dodo.lol", "9-LOL")
|
||||
.addNameserver("ns1.cat.lol", "2-ROID")
|
||||
.addNameserver("ns2.dodo.lol", "7-ROID")
|
||||
.addRegistrar("Yes Virginia <script>")
|
||||
.load("rdap_domain_deleted.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
@@ -647,7 +473,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
|
||||
String label, String tld, DateTime creationTime, DateTime expirationTime) {
|
||||
return persistResource(
|
||||
persistDomainWithDependentResources(
|
||||
label, tld, registrantLol, clock.nowUtc(), creationTime, expirationTime)
|
||||
label, tld, null, clock.nowUtc(), creationTime, expirationTime)
|
||||
.asBuilder()
|
||||
.addNameserver(host1.createVKey())
|
||||
.build());
|
||||
|
||||
@@ -34,7 +34,6 @@ import com.google.common.collect.Range;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import google.registry.model.contact.Contact;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.domain.Period;
|
||||
import google.registry.model.host.Host;
|
||||
@@ -68,9 +67,6 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
private Domain domainCatExample;
|
||||
private Domain domainIdn;
|
||||
private Domain domainMultipart;
|
||||
private Contact contact1;
|
||||
private Contact contact2;
|
||||
private Contact contact3;
|
||||
private Host hostNs1CatLol;
|
||||
private Host hostNs2CatLol;
|
||||
private HashMap<String, Host> hostNameToHostMap = new HashMap<>();
|
||||
@@ -131,15 +127,6 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
persistResource(
|
||||
makeRegistrar("evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE));
|
||||
persistResources(makeRegistrarPocs(registrar));
|
||||
contact1 =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"5372808-ERL", "Goblin Market", "lol@cat.lol", clock.nowUtc().minusYears(1), registrar);
|
||||
contact2 =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"5372808-IRL", "Santa Claus", "BOFH@cat.lol", clock.nowUtc().minusYears(2), registrar);
|
||||
contact3 =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"5372808-TRL", "The Raven", "bog@cat.lol", clock.nowUtc().minusYears(3), registrar);
|
||||
hostNs1CatLol =
|
||||
addHostToMap(
|
||||
FullFieldsTestEntityHelper.makeAndPersistHost(
|
||||
@@ -150,14 +137,7 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
"ns2.cat.lol", "bad:f00d:cafe:0:0:0:15:beef", clock.nowUtc().minusYears(2)));
|
||||
domainCatLol =
|
||||
persistResource(
|
||||
makeDomain(
|
||||
"cat.lol",
|
||||
contact1,
|
||||
contact2,
|
||||
contact3,
|
||||
hostNs1CatLol,
|
||||
hostNs2CatLol,
|
||||
registrar)
|
||||
makeDomain("cat.lol", null, null, null, hostNs1CatLol, hostNs2CatLol, registrar)
|
||||
.asBuilder()
|
||||
.setSubordinateHosts(ImmutableSet.of("ns1.cat.lol", "ns2.cat.lol"))
|
||||
.setCreationTimeForTest(clock.nowUtc().minusYears(3))
|
||||
@@ -172,24 +152,9 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
persistResource(
|
||||
makeDomain(
|
||||
"cat2.lol",
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"6372808-ERL",
|
||||
"Siegmund",
|
||||
"siegmund@cat2.lol",
|
||||
clock.nowUtc().minusYears(1),
|
||||
registrar),
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"6372808-IRL",
|
||||
"Sieglinde",
|
||||
"sieglinde@cat2.lol",
|
||||
clock.nowUtc().minusYears(2),
|
||||
registrar),
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"6372808-TRL",
|
||||
"Siegfried",
|
||||
"siegfried@cat2.lol",
|
||||
clock.nowUtc().minusYears(3),
|
||||
registrar),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
addHostToMap(
|
||||
FullFieldsTestEntityHelper.makeAndPersistHost(
|
||||
"ns1.cat.example", "10.20.30.40", clock.nowUtc().minusYears(1))),
|
||||
@@ -213,24 +178,9 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
persistResource(
|
||||
makeDomain(
|
||||
"cat.example",
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"7372808-ERL",
|
||||
"Matthew",
|
||||
"lol@cat.lol",
|
||||
clock.nowUtc().minusYears(1),
|
||||
registrar),
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"7372808-IRL",
|
||||
"Mark",
|
||||
"BOFH@cat.lol",
|
||||
clock.nowUtc().minusYears(2),
|
||||
registrar),
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"7372808-TRL",
|
||||
"Luke",
|
||||
"bog@cat.lol",
|
||||
clock.nowUtc().minusYears(3),
|
||||
registrar),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
hostNs1CatLol,
|
||||
addHostToMap(
|
||||
FullFieldsTestEntityHelper.makeAndPersistHost(
|
||||
@@ -250,24 +200,9 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
persistResource(
|
||||
makeDomain(
|
||||
"cat.みんな",
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"8372808-ERL",
|
||||
"(◕‿◕)",
|
||||
"lol@cat.みんな",
|
||||
clock.nowUtc().minusYears(1),
|
||||
registrar),
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"8372808-IRL",
|
||||
"Santa Claus",
|
||||
"BOFH@cat.みんな",
|
||||
clock.nowUtc().minusYears(2),
|
||||
registrar),
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"8372808-TRL",
|
||||
"The Raven",
|
||||
"bog@cat.みんな",
|
||||
clock.nowUtc().minusYears(3),
|
||||
registrar),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
addHostToMap(
|
||||
FullFieldsTestEntityHelper.makeAndPersistHost(
|
||||
"ns1.cat.みんな", "1.2.3.5", clock.nowUtc().minusYears(1))),
|
||||
@@ -289,24 +224,9 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
persistResource(
|
||||
makeDomain(
|
||||
"cat.1.test",
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"9372808-ERL",
|
||||
"(◕‿◕)",
|
||||
"lol@cat.みんな",
|
||||
clock.nowUtc().minusYears(1),
|
||||
registrar),
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"9372808-IRL",
|
||||
"Santa Claus",
|
||||
"BOFH@cat.みんな",
|
||||
clock.nowUtc().minusYears(2),
|
||||
registrar),
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"9372808-TRL",
|
||||
"The Raven",
|
||||
"bog@cat.みんな",
|
||||
clock.nowUtc().minusYears(3),
|
||||
registrar),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
addHostToMap(
|
||||
FullFieldsTestEntityHelper.makeAndPersistHost(
|
||||
"ns1.cat.1.test", "1.2.3.5", clock.nowUtc().minusYears(1))),
|
||||
@@ -371,15 +291,15 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
|
||||
private JsonObject generateExpectedJsonForTwoDomainsNsReply() {
|
||||
return jsonFileBuilder()
|
||||
.addDomain("cat.example", "21-EXAMPLE")
|
||||
.addDomain("cat.lol", "C-LOL")
|
||||
.addDomain("cat.example", "F-EXAMPLE")
|
||||
.addDomain("cat.lol", "6-LOL")
|
||||
.load("rdap_domains_two.json");
|
||||
}
|
||||
|
||||
private JsonObject generateExpectedJsonForTwoDomainsCatStarReplySql() {
|
||||
return jsonFileBuilder()
|
||||
.addDomain("cat.lol", "C-LOL")
|
||||
.addDomain("cat2.lol", "17-LOL")
|
||||
.addDomain("cat.lol", "6-LOL")
|
||||
.addDomain("cat2.lol", "B-LOL")
|
||||
.load("rdap_domains_two.json");
|
||||
}
|
||||
|
||||
@@ -416,7 +336,7 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
for (int i = numActiveDomains * numTotalDomainsPerActiveDomain; i >= 1; i--) {
|
||||
String domainName = String.format("domain%d.lol", i);
|
||||
Domain.Builder builder =
|
||||
makeDomain(domainName, contact1, contact2, contact3, null, null, registrar)
|
||||
makeDomain(domainName, null, null, null, null, null, registrar)
|
||||
.asBuilder()
|
||||
.setNameservers(hostKeys)
|
||||
.setCreationTimeForTest(clock.nowUtc().minusYears(3))
|
||||
@@ -442,13 +362,10 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
requestType,
|
||||
queryString,
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.lol", "C-LOL")
|
||||
.addDomain("cat.lol", "6-LOL")
|
||||
.addRegistrar("Yes Virginia <script>")
|
||||
.addNameserver("ns1.cat.lol", "8-ROID")
|
||||
.addNameserver("ns2.cat.lol", "A-ROID")
|
||||
.addContact("4-ROID")
|
||||
.addContact("6-ROID")
|
||||
.addContact("2-ROID")
|
||||
.addNameserver("ns1.cat.lol", "2-ROID")
|
||||
.addNameserver("ns2.cat.lol", "4-ROID")
|
||||
.setNextQuery(queryString)
|
||||
.load(filename));
|
||||
}
|
||||
@@ -459,13 +376,10 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
requestType,
|
||||
queryString,
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat2.lol", "17-LOL")
|
||||
.addDomain("cat2.lol", "B-LOL")
|
||||
.addRegistrar("Yes Virginia <script>")
|
||||
.addNameserver("ns1.cat.example", "13-ROID")
|
||||
.addNameserver("ns2.dog.lol", "15-ROID")
|
||||
.addContact("F-ROID")
|
||||
.addContact("11-ROID")
|
||||
.addContact("D-ROID")
|
||||
.addNameserver("ns1.cat.example", "7-ROID")
|
||||
.addNameserver("ns2.dog.lol", "9-ROID")
|
||||
.setNextQuery(queryString)
|
||||
.load(filename));
|
||||
}
|
||||
@@ -573,7 +487,6 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
action.registrarParam.isPresent(),
|
||||
numDomainsRetrieved,
|
||||
numHostsRetrieved,
|
||||
Optional.empty(),
|
||||
incompletenessWarningType);
|
||||
}
|
||||
|
||||
@@ -747,8 +660,7 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
@Test
|
||||
void testDomainMatch_found_loggedInAsOtherRegistrar() {
|
||||
login("otherregistrar");
|
||||
runSuccessfulTestWithCatLol(
|
||||
RequestType.NAME, "cat.lol", "rdap_domain_redacted_contacts_with_remark.json");
|
||||
runSuccessfulTestWithCatLol(RequestType.NAME, "cat.lol", "rdap_domain.json");
|
||||
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L));
|
||||
}
|
||||
|
||||
@@ -776,11 +688,11 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
RequestType.NAME,
|
||||
"cat.example",
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.example", "21-EXAMPLE")
|
||||
.addDomain("cat.example", "F-EXAMPLE")
|
||||
.addRegistrar("St. John Chrysostom")
|
||||
.addNameserver("ns1.cat.lol", "8-ROID")
|
||||
.addNameserver("ns2.external.tld", "1F-ROID")
|
||||
.load("rdap_domain_redacted_contacts_with_remark.json"));
|
||||
.addNameserver("ns1.cat.lol", "2-ROID")
|
||||
.addNameserver("ns2.external.tld", "D-ROID")
|
||||
.load("rdap_domain.json"));
|
||||
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L));
|
||||
}
|
||||
|
||||
@@ -790,11 +702,11 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
RequestType.NAME,
|
||||
"cat.みんな",
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.みんな", "2D-Q9JYB4C")
|
||||
.addDomain("cat.みんな", "15-Q9JYB4C")
|
||||
.addRegistrar("みんな")
|
||||
.addNameserver("ns1.cat.みんな", "29-ROID")
|
||||
.addNameserver("ns2.cat.みんな", "2B-ROID")
|
||||
.load("rdap_domain_unicode_no_contacts_with_remark.json"));
|
||||
.addNameserver("ns1.cat.みんな", "11-ROID")
|
||||
.addNameserver("ns2.cat.みんな", "13-ROID")
|
||||
.load("rdap_domain_unicode_with_unicode_nameservers.json"));
|
||||
// The unicode gets translated to ASCII before getting parsed into a search pattern.
|
||||
metricPrefixLength = 15;
|
||||
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L));
|
||||
@@ -806,11 +718,11 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
RequestType.NAME,
|
||||
"cat.xn--q9jyb4c",
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.みんな", "2D-Q9JYB4C")
|
||||
.addDomain("cat.みんな", "15-Q9JYB4C")
|
||||
.addRegistrar("みんな")
|
||||
.addNameserver("ns1.cat.みんな", "29-ROID")
|
||||
.addNameserver("ns2.cat.みんな", "2B-ROID")
|
||||
.load("rdap_domain_unicode_no_contacts_with_remark.json"));
|
||||
.addNameserver("ns1.cat.みんな", "11-ROID")
|
||||
.addNameserver("ns2.cat.みんな", "13-ROID")
|
||||
.load("rdap_domain_unicode_with_unicode_nameservers.json"));
|
||||
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L));
|
||||
}
|
||||
|
||||
@@ -820,11 +732,11 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
RequestType.NAME,
|
||||
"cat.1.test",
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.1.test", "39-1_TEST")
|
||||
.addDomain("cat.1.test", "1B-1_TEST")
|
||||
.addRegistrar("1.test")
|
||||
.addNameserver("ns1.cat.1.test", "35-ROID")
|
||||
.addNameserver("ns2.cat.2.test", "37-ROID")
|
||||
.load("rdap_domain_redacted_contacts_with_remark.json"));
|
||||
.addNameserver("ns1.cat.1.test", "17-ROID")
|
||||
.addNameserver("ns2.cat.2.test", "19-ROID")
|
||||
.load("rdap_domain.json"));
|
||||
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L));
|
||||
}
|
||||
|
||||
@@ -834,11 +746,11 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
RequestType.NAME,
|
||||
"ca*.1.test",
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.1.test", "39-1_TEST")
|
||||
.addDomain("cat.1.test", "1B-1_TEST")
|
||||
.addRegistrar("1.test")
|
||||
.addNameserver("ns1.cat.1.test", "35-ROID")
|
||||
.addNameserver("ns2.cat.2.test", "37-ROID")
|
||||
.load("rdap_domain_redacted_contacts_with_remark.json"));
|
||||
.addNameserver("ns1.cat.1.test", "17-ROID")
|
||||
.addNameserver("ns2.cat.2.test", "19-ROID")
|
||||
.load("rdap_domain.json"));
|
||||
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(1L));
|
||||
}
|
||||
|
||||
@@ -910,10 +822,10 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
.that(generateActualJson(RequestType.NAME, "cat.*"))
|
||||
.isEqualTo(
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.1.test", "39-1_TEST")
|
||||
.addDomain("cat.example", "21-EXAMPLE")
|
||||
.addDomain("cat.lol", "C-LOL")
|
||||
.addDomain("cat.みんな", "2D-Q9JYB4C")
|
||||
.addDomain("cat.1.test", "1B-1_TEST")
|
||||
.addDomain("cat.example", "F-EXAMPLE")
|
||||
.addDomain("cat.lol", "6-LOL")
|
||||
.addDomain("cat.みんな", "15-Q9JYB4C")
|
||||
.load("rdap_domains_four_with_one_unicode.json"));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(4L));
|
||||
@@ -948,10 +860,10 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
.that(generateActualJson(RequestType.NAME, "cat*"))
|
||||
.isEqualTo(
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.1.test", "39-1_TEST")
|
||||
.addDomain("cat.example", "21-EXAMPLE")
|
||||
.addDomain("cat.lol", "C-LOL")
|
||||
.addDomain("cat.みんな", "2D-Q9JYB4C")
|
||||
.addDomain("cat.1.test", "1B-1_TEST")
|
||||
.addDomain("cat.example", "F-EXAMPLE")
|
||||
.addDomain("cat.lol", "6-LOL")
|
||||
.addDomain("cat.みんな", "15-Q9JYB4C")
|
||||
.setNextQuery("name=cat*&cursor=Y2F0LnhuLS1xOWp5YjRj")
|
||||
.load("rdap_domains_four_with_one_unicode_truncated.json"));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
@@ -1031,7 +943,7 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
verifyErrorMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(2L), 404);
|
||||
}
|
||||
|
||||
// TODO(b/27378695): reenable or delete this test
|
||||
// TODO(b/27376E-95): reenable or delete this test
|
||||
@Disabled
|
||||
@Test
|
||||
void testDomainMatchDomainInTestTld_notFound() {
|
||||
@@ -1073,9 +985,9 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
.that(generateActualJson(RequestType.NAME, "domain*.lol"))
|
||||
.isEqualTo(
|
||||
jsonFileBuilder()
|
||||
.addDomain("domain100.lol", "AC-LOL")
|
||||
.addDomain("domain150.lol", "7A-LOL")
|
||||
.addDomain("domain200.lol", "48-LOL")
|
||||
.addDomain("domain100.lol", "8E-LOL")
|
||||
.addDomain("domain150.lol", "5C-LOL")
|
||||
.addDomain("domain200.lol", "2A-LOL")
|
||||
.addDomain("domainunused.lol", "unused-LOL")
|
||||
.load("rdap_incomplete_domain_result_set.json"));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
@@ -1091,10 +1003,10 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
runSuccessfulTestWithFourDomains(
|
||||
RequestType.NAME,
|
||||
"domain*.lol",
|
||||
"4B-LOL",
|
||||
"4A-LOL",
|
||||
"49-LOL",
|
||||
"48-LOL",
|
||||
"2D-LOL",
|
||||
"2C-LOL",
|
||||
"2B-LOL",
|
||||
"2A-LOL",
|
||||
"rdap_nontruncated_domains.json");
|
||||
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(4L));
|
||||
}
|
||||
@@ -1105,10 +1017,10 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
runSuccessfulTestWithFourDomains(
|
||||
RequestType.NAME,
|
||||
"domain*.lol",
|
||||
"4C-LOL",
|
||||
"4B-LOL",
|
||||
"4A-LOL",
|
||||
"49-LOL",
|
||||
"2E-LOL",
|
||||
"2D-LOL",
|
||||
"2C-LOL",
|
||||
"2B-LOL",
|
||||
"name=domain*.lol&cursor=ZG9tYWluNC5sb2w%3D",
|
||||
"rdap_domains_four_truncated.json");
|
||||
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(5L), IncompletenessWarningType.TRUNCATED);
|
||||
@@ -1122,10 +1034,10 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
.that(generateActualJson(RequestType.NAME, "*.lol"))
|
||||
.isEqualTo(
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.lol", "C-LOL")
|
||||
.addDomain("cat2.lol", "17-LOL")
|
||||
.addDomain("domain1.lol", "4B-LOL")
|
||||
.addDomain("domain2.lol", "4A-LOL")
|
||||
.addDomain("cat.lol", "6-LOL")
|
||||
.addDomain("cat2.lol", "B-LOL")
|
||||
.addDomain("domain1.lol", "2D-LOL")
|
||||
.addDomain("domain2.lol", "2C-LOL")
|
||||
.setNextQuery("name=*.lol&cursor=ZG9tYWluMi5sb2w%3D")
|
||||
.load("rdap_domains_four_truncated.json"));
|
||||
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(5L), IncompletenessWarningType.TRUNCATED);
|
||||
@@ -1139,10 +1051,10 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
runSuccessfulTestWithFourDomains(
|
||||
RequestType.NAME,
|
||||
"domain*.lol",
|
||||
"50-LOL",
|
||||
"4F-LOL",
|
||||
"4E-LOL",
|
||||
"4D-LOL",
|
||||
"32-LOL",
|
||||
"31-LOL",
|
||||
"30-LOL",
|
||||
"2F-LOL",
|
||||
"name=domain*.lol&cursor=ZG9tYWluNC5sb2w%3D",
|
||||
"rdap_domains_four_truncated.json");
|
||||
verifyMetrics(SearchType.BY_DOMAIN_NAME, Optional.of(5L), IncompletenessWarningType.TRUNCATED);
|
||||
@@ -1156,10 +1068,10 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
.that(generateActualJson(RequestType.NAME, "domain*.lol"))
|
||||
.isEqualTo(
|
||||
jsonFileBuilder()
|
||||
.addDomain("domain12.lol", "5A-LOL")
|
||||
.addDomain("domain18.lol", "54-LOL")
|
||||
.addDomain("domain24.lol", "4E-LOL")
|
||||
.addDomain("domain30.lol", "48-LOL")
|
||||
.addDomain("domain12.lol", "3C-LOL")
|
||||
.addDomain("domain18.lol", "36-LOL")
|
||||
.addDomain("domain24.lol", "30-LOL")
|
||||
.addDomain("domain30.lol", "2A-LOL")
|
||||
.setNextQuery("name=domain*.lol&cursor=ZG9tYWluMzAubG9s")
|
||||
.load("rdap_domains_four_truncated.json"));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
@@ -1358,11 +1270,11 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
RequestType.NS_LDH_NAME,
|
||||
"ns1.cat.xn--q9jyb4c",
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.みんな", "2D-Q9JYB4C")
|
||||
.addDomain("cat.みんな", "15-Q9JYB4C")
|
||||
.addRegistrar("みんな")
|
||||
.addNameserver("ns1.cat.みんな", "29-ROID")
|
||||
.addNameserver("ns2.cat.みんな", "2B-ROID")
|
||||
.load("rdap_domain_unicode_no_contacts_with_remark.json"));
|
||||
.addNameserver("ns1.cat.みんな", "11-ROID")
|
||||
.addNameserver("ns2.cat.みんな", "13-ROID")
|
||||
.load("rdap_domain_unicode_with_unicode_nameservers.json"));
|
||||
verifyMetrics(SearchType.BY_NAMESERVER_NAME, 1, 1);
|
||||
}
|
||||
|
||||
@@ -1372,11 +1284,11 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
RequestType.NS_LDH_NAME,
|
||||
"ns1.cat.1.test",
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.1.test", "39-1_TEST")
|
||||
.addDomain("cat.1.test", "1B-1_TEST")
|
||||
.addRegistrar("1.test")
|
||||
.addNameserver("ns1.cat.1.test", "35-ROID")
|
||||
.addNameserver("ns2.cat.2.test", "37-ROID")
|
||||
.load("rdap_domain_redacted_contacts_with_remark.json"));
|
||||
.addNameserver("ns1.cat.1.test", "17-ROID")
|
||||
.addNameserver("ns2.cat.2.test", "19-ROID")
|
||||
.load("rdap_domain.json"));
|
||||
verifyMetrics(SearchType.BY_NAMESERVER_NAME, 1, 1);
|
||||
}
|
||||
|
||||
@@ -1386,11 +1298,11 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
RequestType.NS_LDH_NAME,
|
||||
"ns*.cat.1.test",
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.1.test", "39-1_TEST")
|
||||
.addDomain("cat.1.test", "1B-1_TEST")
|
||||
.addRegistrar("1.test")
|
||||
.addNameserver("ns1.cat.1.test", "35-ROID")
|
||||
.addNameserver("ns2.cat.2.test", "37-ROID")
|
||||
.load("rdap_domain_redacted_contacts_with_remark.json"));
|
||||
.addNameserver("ns1.cat.1.test", "17-ROID")
|
||||
.addNameserver("ns2.cat.2.test", "19-ROID")
|
||||
.load("rdap_domain.json"));
|
||||
verifyMetrics(SearchType.BY_NAMESERVER_NAME, 1, 1);
|
||||
}
|
||||
|
||||
@@ -1408,7 +1320,7 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
verifyErrorMetrics(SearchType.BY_NAMESERVER_NAME, Optional.empty(), Optional.of(0L), 404);
|
||||
}
|
||||
|
||||
// TODO(b/27378695): reenable or delete this test
|
||||
// TODO(b/27376E-95): reenable or delete this test
|
||||
@Disabled
|
||||
@Test
|
||||
void testNameserverMatchDomainsInTestTld_notFound() {
|
||||
@@ -1531,10 +1443,10 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
runSuccessfulTestWithFourDomains(
|
||||
RequestType.NS_LDH_NAME,
|
||||
"ns1.domain1.lol",
|
||||
"4B-LOL",
|
||||
"4A-LOL",
|
||||
"49-LOL",
|
||||
"48-LOL",
|
||||
"2D-LOL",
|
||||
"2C-LOL",
|
||||
"2B-LOL",
|
||||
"2A-LOL",
|
||||
"rdap_nontruncated_domains.json");
|
||||
verifyMetrics(SearchType.BY_NAMESERVER_NAME, Optional.of(4L), Optional.of(1L));
|
||||
}
|
||||
@@ -1545,10 +1457,10 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
runSuccessfulTestWithFourDomains(
|
||||
RequestType.NS_LDH_NAME,
|
||||
"ns1.domain1.lol",
|
||||
"4C-LOL",
|
||||
"4B-LOL",
|
||||
"4A-LOL",
|
||||
"49-LOL",
|
||||
"2E-LOL",
|
||||
"2D-LOL",
|
||||
"2C-LOL",
|
||||
"2B-LOL",
|
||||
"nsLdhName=ns1.domain1.lol&cursor=ZG9tYWluNC5sb2w%3D",
|
||||
"rdap_domains_four_truncated.json");
|
||||
verifyMetrics(
|
||||
@@ -1564,10 +1476,10 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
runSuccessfulTestWithFourDomains(
|
||||
RequestType.NS_LDH_NAME,
|
||||
"ns1.domain1.lol",
|
||||
"50-LOL",
|
||||
"4F-LOL",
|
||||
"4E-LOL",
|
||||
"4D-LOL",
|
||||
"32-LOL",
|
||||
"31-LOL",
|
||||
"30-LOL",
|
||||
"2F-LOL",
|
||||
"nsLdhName=ns1.domain1.lol&cursor=ZG9tYWluNC5sb2w%3D",
|
||||
"rdap_domains_four_truncated.json");
|
||||
verifyMetrics(
|
||||
@@ -1587,10 +1499,10 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
.that(generateActualJson(RequestType.NS_LDH_NAME, "ns*.domain1.lol"))
|
||||
.isEqualTo(
|
||||
jsonFileBuilder()
|
||||
.addDomain("domain1.lol", "8F-LOL")
|
||||
.addDomain("domain2.lol", "8E-LOL")
|
||||
.addDomain("domain3.lol", "8D-LOL")
|
||||
.addDomain("domain4.lol", "8C-LOL")
|
||||
.addDomain("domain1.lol", "71-LOL")
|
||||
.addDomain("domain2.lol", "70-LOL")
|
||||
.addDomain("domain3.lol", "6F-LOL")
|
||||
.addDomain("domain4.lol", "6E-LOL")
|
||||
.load("rdap_nontruncated_domains.json"));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
verifyMetrics(SearchType.BY_NAMESERVER_NAME, Optional.of(4L), Optional.of(36L));
|
||||
@@ -1604,8 +1516,8 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
.that(generateActualJson(RequestType.NS_LDH_NAME, "ns*.domain1.lol"))
|
||||
.isEqualTo(
|
||||
jsonFileBuilder()
|
||||
.addDomain("domain1.lol", "97-LOL")
|
||||
.addDomain("domain2.lol", "96-LOL")
|
||||
.addDomain("domain1.lol", "79-LOL")
|
||||
.addDomain("domain2.lol", "78-LOL")
|
||||
.load("rdap_incomplete_domains.json"));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
verifyMetrics(
|
||||
@@ -1671,9 +1583,7 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
@Test
|
||||
void testAddressMatchV6Address_foundOne() {
|
||||
runSuccessfulTestWithCatLol(
|
||||
RequestType.NS_IP,
|
||||
"bad:f00d:cafe:0:0:0:15:beef",
|
||||
"rdap_domain_redacted_contacts_with_remark.json");
|
||||
RequestType.NS_IP, "bad:f00d:cafe:0:0:0:15:beef", "rdap_domain.json");
|
||||
verifyMetrics(SearchType.BY_NAMESERVER_ADDRESS, 1, 1);
|
||||
}
|
||||
|
||||
@@ -1683,7 +1593,7 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
verifyErrorMetrics(SearchType.BY_NAMESERVER_ADDRESS, Optional.empty(), Optional.of(0L), 404);
|
||||
}
|
||||
|
||||
// TODO(b/27378695): reenable or delete this test
|
||||
// TODO(b/27376E-95): reenable or delete this test
|
||||
@Disabled
|
||||
@Test
|
||||
void testAddressMatchDomainsInTestTld_notFound() {
|
||||
@@ -1740,13 +1650,10 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
.isEqualTo(
|
||||
wrapInSearchReply(
|
||||
jsonFileBuilder()
|
||||
.addDomain("cat.lol", "C-LOL")
|
||||
.addDomain("cat.lol", "6-LOL")
|
||||
.addRegistrar("Yes Virginia <script>")
|
||||
.addNameserver("ns1.cat.lol", "8-ROID")
|
||||
.addNameserver("ns2.cat.lol", "A-ROID")
|
||||
.addContact("4-ROID")
|
||||
.addContact("6-ROID")
|
||||
.addContact("2-ROID")
|
||||
.addNameserver("ns1.cat.lol", "2-ROID")
|
||||
.addNameserver("ns2.cat.lol", "4-ROID")
|
||||
.load("rdap_domain.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
verifyMetrics(SearchType.BY_NAMESERVER_ADDRESS, 1, 1);
|
||||
@@ -1773,10 +1680,10 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
runSuccessfulTestWithFourDomains(
|
||||
RequestType.NS_IP,
|
||||
"5.5.5.1",
|
||||
"4B-LOL",
|
||||
"4A-LOL",
|
||||
"49-LOL",
|
||||
"48-LOL",
|
||||
"2D-LOL",
|
||||
"2C-LOL",
|
||||
"2B-LOL",
|
||||
"2A-LOL",
|
||||
"rdap_nontruncated_domains.json");
|
||||
verifyMetrics(SearchType.BY_NAMESERVER_ADDRESS, 4, 1);
|
||||
}
|
||||
@@ -1787,10 +1694,10 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
runSuccessfulTestWithFourDomains(
|
||||
RequestType.NS_IP,
|
||||
"5.5.5.1",
|
||||
"4C-LOL",
|
||||
"4B-LOL",
|
||||
"4A-LOL",
|
||||
"49-LOL",
|
||||
"2E-LOL",
|
||||
"2D-LOL",
|
||||
"2C-LOL",
|
||||
"2B-LOL",
|
||||
"nsIp=5.5.5.1&cursor=ZG9tYWluNC5sb2w%3D",
|
||||
"rdap_domains_four_truncated.json");
|
||||
verifyMetrics(
|
||||
@@ -1806,10 +1713,10 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase<RdapDomainSear
|
||||
runSuccessfulTestWithFourDomains(
|
||||
RequestType.NS_IP,
|
||||
"5.5.5.1",
|
||||
"50-LOL",
|
||||
"4F-LOL",
|
||||
"4E-LOL",
|
||||
"4D-LOL",
|
||||
"32-LOL",
|
||||
"31-LOL",
|
||||
"30-LOL",
|
||||
"2F-LOL",
|
||||
"nsIp=5.5.5.1&cursor=ZG9tYWluNC5sb2w%3D",
|
||||
"rdap_domains_four_truncated.json");
|
||||
verifyMetrics(
|
||||
|
||||
@@ -18,7 +18,6 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.testing.DatabaseHelper.persistResources;
|
||||
import static google.registry.testing.FullFieldsTestEntityHelper.makeAndPersistDeletedContact;
|
||||
import static google.registry.testing.FullFieldsTestEntityHelper.makeDomain;
|
||||
import static google.registry.testing.FullFieldsTestEntityHelper.makeHost;
|
||||
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
|
||||
@@ -26,8 +25,6 @@ import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrarPo
|
||||
import static google.registry.testing.GsonSubject.assertAboutJson;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import google.registry.model.contact.Contact;
|
||||
import google.registry.model.host.Host;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.rdap.RdapMetrics.EndpointType;
|
||||
@@ -35,7 +32,6 @@ import google.registry.rdap.RdapMetrics.SearchType;
|
||||
import google.registry.rdap.RdapMetrics.WildcardType;
|
||||
import google.registry.rdap.RdapSearchResults.IncompletenessWarningType;
|
||||
import google.registry.request.Action;
|
||||
import google.registry.testing.FullFieldsTestEntityHelper;
|
||||
import java.util.Optional;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -43,19 +39,11 @@ import org.junit.jupiter.api.Test;
|
||||
/** Unit tests for {@link RdapEntityAction}. */
|
||||
class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
|
||||
|
||||
private static final String CONTACT_NAME = "(◕‿◕)";
|
||||
private static final String CONTACT_ADDRESS = "\"1 Smiley Row\", \"Suite みんな\"";
|
||||
|
||||
RdapEntityActionTest() {
|
||||
super(RdapEntityAction.class);
|
||||
}
|
||||
|
||||
private Registrar registrarLol;
|
||||
private Contact registrant;
|
||||
private Contact adminContact;
|
||||
private Contact techContact;
|
||||
private Contact disconnectedContact;
|
||||
private Contact deletedContact;
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
@@ -64,34 +52,9 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
|
||||
registrarLol = persistResource(makeRegistrar(
|
||||
"evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE, 101L));
|
||||
persistResources(makeRegistrarPocs(registrarLol));
|
||||
registrant =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"8372808-REG",
|
||||
CONTACT_NAME,
|
||||
"lol@cat.みんな",
|
||||
ImmutableList.of("1 Smiley Row", "Suite みんな"),
|
||||
clock.nowUtc(),
|
||||
registrarLol);
|
||||
adminContact =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"8372808-ADM",
|
||||
CONTACT_NAME,
|
||||
"lol@cat.みんな",
|
||||
ImmutableList.of("1 Smiley Row", "Suite みんな"),
|
||||
clock.nowUtc(),
|
||||
registrarLol);
|
||||
techContact =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"8372808-TEC",
|
||||
CONTACT_NAME,
|
||||
"lol@cat.みんな",
|
||||
ImmutableList.of("1 Smiley Row", "Suite みんな"),
|
||||
clock.nowUtc(),
|
||||
registrarLol);
|
||||
Host host1 = persistResource(makeHost("ns1.cat.lol", "1.2.3.4"));
|
||||
Host host2 = persistResource(makeHost("ns2.cat.lol", "bad:f00d:cafe:0:0:0:15:beef"));
|
||||
persistResource(
|
||||
makeDomain("cat.lol", registrant, adminContact, techContact, host1, host2, registrarLol));
|
||||
persistResource(makeDomain("cat.lol", null, null, null, host1, host2, registrarLol));
|
||||
// xn--q9jyb4c
|
||||
createTld("xn--q9jyb4c");
|
||||
Registrar registrarIdn = persistResource(
|
||||
@@ -106,21 +69,6 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
|
||||
Registrar registrarDeleted = persistResource(
|
||||
makeRegistrar("deletedregistrar", "Yes Virginia <script>", Registrar.State.PENDING, 104L));
|
||||
persistResources(makeRegistrarPocs(registrarDeleted));
|
||||
// other contacts
|
||||
disconnectedContact =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"8372808-DIS",
|
||||
CONTACT_NAME,
|
||||
"lol@cat.みんな",
|
||||
ImmutableList.of("1 Smiley Row", "Suite みんな"),
|
||||
clock.nowUtc(),
|
||||
registrarLol);
|
||||
deletedContact =
|
||||
makeAndPersistDeletedContact(
|
||||
"8372808-DEL",
|
||||
clock.nowUtc().minusYears(1),
|
||||
registrarLol,
|
||||
clock.nowUtc().minusMonths(6));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -148,156 +96,6 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidRegistrantContact_works() {
|
||||
login("evilregistrar");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(registrant.getRepoId()))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addFullContact(registrant.getRepoId(), null, CONTACT_NAME, CONTACT_ADDRESS)
|
||||
.load("rdap_associated_contact.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidRegistrantContact_found_asAdministrator() {
|
||||
loginAsAdmin();
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(registrant.getRepoId()))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addFullContact(registrant.getRepoId(), null, CONTACT_NAME, CONTACT_ADDRESS)
|
||||
.load("rdap_associated_contact.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidRegistrantContact_found_notLoggedIn() {
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(registrant.getRepoId()))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addFullContact(registrant.getRepoId(), "active", CONTACT_NAME, CONTACT_ADDRESS)
|
||||
.load("rdap_associated_contact_no_personal_data.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidRegistrantContact_found_loggedInAsOtherRegistrar() {
|
||||
login("otherregistrar");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(registrant.getRepoId()))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addFullContact(registrant.getRepoId(), "active", CONTACT_NAME, CONTACT_ADDRESS)
|
||||
.load("rdap_associated_contact_no_personal_data.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidAdminContact_works() {
|
||||
login("evilregistrar");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(adminContact.getRepoId()))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addFullContact(adminContact.getRepoId(), null, CONTACT_NAME, CONTACT_ADDRESS)
|
||||
.load("rdap_associated_contact.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidTechContact_works() {
|
||||
login("evilregistrar");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(techContact.getRepoId()))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addFullContact(techContact.getRepoId(), null, CONTACT_NAME, CONTACT_ADDRESS)
|
||||
.load("rdap_associated_contact.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidDisconnectedContact_works() {
|
||||
login("evilregistrar");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(disconnectedContact.getRepoId()))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addFullContact(
|
||||
disconnectedContact.getRepoId(), "active", CONTACT_NAME, CONTACT_ADDRESS)
|
||||
.load("rdap_contact.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeletedContact_notFound() {
|
||||
String repoId = deletedContact.getRepoId();
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(repoId))
|
||||
.isEqualTo(generateExpectedJsonError(repoId + " not found", 404));
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeletedContact_notFound_includeDeletedSetFalse() {
|
||||
action.includeDeletedParam = Optional.of(false);
|
||||
String repoId = deletedContact.getRepoId();
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(repoId))
|
||||
.isEqualTo(generateExpectedJsonError(repoId + " not found", 404));
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeletedContact_notFound_notLoggedIn() {
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
String repoId = deletedContact.getRepoId();
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(repoId))
|
||||
.isEqualTo(generateExpectedJsonError(repoId + " not found", 404));
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeletedContact_notFound_loggedInAsDifferentRegistrar() {
|
||||
login("idnregistrar");
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
String repoId = deletedContact.getRepoId();
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(repoId))
|
||||
.isEqualTo(generateExpectedJsonError(repoId + " not found", 404));
|
||||
assertThat(response.getStatus()).isEqualTo(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeletedContact_found_loggedInAsCorrectRegistrar() {
|
||||
login("evilregistrar");
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(deletedContact.getRepoId()))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addContact(deletedContact.getRepoId())
|
||||
.load("rdap_contact_deleted.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeletedContact_found_loggedInAsAdmin() {
|
||||
loginAsAdmin();
|
||||
action.includeDeletedParam = Optional.of(true);
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(deletedContact.getRepoId()))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addContact(deletedContact.getRepoId())
|
||||
.load("rdap_contact_deleted.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRegistrar_found() {
|
||||
assertAboutJson()
|
||||
@@ -412,18 +210,18 @@ class RdapEntityActionTest extends RdapActionBaseTestCase<RdapEntityAction> {
|
||||
void testQueryParameter_ignored() {
|
||||
login("evilregistrar");
|
||||
assertAboutJson()
|
||||
.that(generateActualJson(techContact.getRepoId() + "?key=value"))
|
||||
.that(generateActualJson("101?key=value"))
|
||||
.isEqualTo(
|
||||
addPermanentBoilerplateNotices(
|
||||
jsonFileBuilder()
|
||||
.addFullContact(techContact.getRepoId(), null, CONTACT_NAME, CONTACT_ADDRESS)
|
||||
.load("rdap_associated_contact.json")));
|
||||
.addFullRegistrar("101", "Yes Virginia <script>", "active", null)
|
||||
.load("rdap_registrar.json")));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMetrics() {
|
||||
generateActualJson(registrant.getRepoId());
|
||||
generateActualJson("101");
|
||||
verify(rdapMetrics)
|
||||
.updateMetrics(
|
||||
RdapMetrics.RdapMetricInformation.builder()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -33,7 +33,6 @@ import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import google.registry.model.contact.Contact;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
import google.registry.model.host.Host;
|
||||
@@ -46,12 +45,9 @@ import google.registry.persistence.transaction.JpaTestExtensions;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
|
||||
import google.registry.rdap.RdapJsonFormatter.OutputDataType;
|
||||
import google.registry.rdap.RdapObjectClasses.BoilerplateType;
|
||||
import google.registry.rdap.RdapObjectClasses.RdapEntity;
|
||||
import google.registry.rdap.RdapObjectClasses.ReplyPayloadBase;
|
||||
import google.registry.rdap.RdapObjectClasses.TopLevelReplyObject;
|
||||
import google.registry.testing.FakeClock;
|
||||
import google.registry.testing.FullFieldsTestEntityHelper;
|
||||
import javax.annotation.Nullable;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -77,10 +73,6 @@ class RdapJsonFormatterTest {
|
||||
private Host hostNoAddresses;
|
||||
private Host hostNotLinked;
|
||||
private Host hostSuperordinatePendingTransfer;
|
||||
@Nullable private Contact contactRegistrant;
|
||||
private Contact contactAdmin;
|
||||
private Contact contactTech;
|
||||
private Contact contactNotLinked;
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
@@ -95,35 +87,8 @@ class RdapJsonFormatterTest {
|
||||
clock.setTo(DateTime.parse("2000-01-01T00:00:00Z"));
|
||||
registrar = persistResource(registrar);
|
||||
|
||||
persistResources(makeMoreRegistrarContacts(registrar));
|
||||
persistResources(makeMoreRegistrarPocs(registrar));
|
||||
|
||||
contactRegistrant =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"8372808-ERL", "(◕‿◕)", "lol@cat.みんな", null, clock.nowUtc().minusYears(1), registrar);
|
||||
contactAdmin =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"8372808-IRL",
|
||||
"Santa Claus",
|
||||
null,
|
||||
ImmutableList.of("Santa Claus Tower", "41st floor", "Suite みんな"),
|
||||
clock.nowUtc().minusYears(2),
|
||||
registrar);
|
||||
contactTech =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"8372808-TRL",
|
||||
"The Raven",
|
||||
"bog@cat.みんな",
|
||||
ImmutableList.of("Chamber Door", "upper level"),
|
||||
clock.nowUtc().minusYears(3),
|
||||
registrar);
|
||||
contactNotLinked =
|
||||
FullFieldsTestEntityHelper.makeAndPersistContact(
|
||||
"8372808-QRL",
|
||||
"The Wizard",
|
||||
"dog@cat.みんな",
|
||||
ImmutableList.of("Somewhere", "Over the Rainbow"),
|
||||
clock.nowUtc().minusYears(4),
|
||||
registrar);
|
||||
hostIpv4 =
|
||||
makeAndPersistHost(
|
||||
"ns1.cat.みんな", "1.2.3.4", null, clock.nowUtc().minusYears(1), "unicoderegistrar");
|
||||
@@ -154,14 +119,7 @@ class RdapJsonFormatterTest {
|
||||
.asBuilder()
|
||||
.setSuperordinateDomain(
|
||||
persistResource(
|
||||
makeDomain(
|
||||
"dog.みんな",
|
||||
contactRegistrant,
|
||||
contactAdmin,
|
||||
contactTech,
|
||||
null,
|
||||
null,
|
||||
registrar)
|
||||
makeDomain("dog.みんな", null, null, null, null, null, registrar)
|
||||
.asBuilder()
|
||||
.addStatusValue(StatusValue.PENDING_TRANSFER)
|
||||
.setTransferData(
|
||||
@@ -180,43 +138,21 @@ class RdapJsonFormatterTest {
|
||||
.build());
|
||||
domainFull =
|
||||
persistResource(
|
||||
makeDomain(
|
||||
"cat.みんな",
|
||||
contactRegistrant,
|
||||
contactAdmin,
|
||||
contactTech,
|
||||
hostIpv4,
|
||||
hostIpv6,
|
||||
registrar)
|
||||
makeDomain("cat.みんな", null, null, null, hostIpv4, hostIpv6, registrar)
|
||||
.asBuilder()
|
||||
.setCreationTimeForTest(clock.nowUtc().minusMonths(4))
|
||||
.setLastEppUpdateTime(clock.nowUtc().minusMonths(3))
|
||||
.build());
|
||||
domainNoNameserversNoTransfers =
|
||||
persistResource(
|
||||
makeDomain(
|
||||
"fish.みんな",
|
||||
contactRegistrant,
|
||||
contactRegistrant,
|
||||
contactRegistrant,
|
||||
null,
|
||||
null,
|
||||
registrar)
|
||||
makeDomain("fish.みんな", null, null, null, null, null, registrar)
|
||||
.asBuilder()
|
||||
.setCreationTimeForTest(clock.nowUtc())
|
||||
.setLastEppUpdateTime(null)
|
||||
.build());
|
||||
// Create an unused domain that references hostBoth and hostNoAddresses so that
|
||||
// they will have "associated" (ie, StatusValue.LINKED) status.
|
||||
persistResource(
|
||||
makeDomain(
|
||||
"dog.みんな",
|
||||
contactRegistrant,
|
||||
contactAdmin,
|
||||
contactTech,
|
||||
hostBoth,
|
||||
hostNoAddresses,
|
||||
registrar));
|
||||
persistResource(makeDomain("dog.みんな", null, null, null, hostBoth, hostNoAddresses, registrar));
|
||||
|
||||
// history entries
|
||||
// We create 3 "transfer approved" entries, to make sure we only save the last one
|
||||
@@ -252,7 +188,7 @@ class RdapJsonFormatterTest {
|
||||
clock.nowUtc().minusMonths(3)));
|
||||
}
|
||||
|
||||
static ImmutableList<RegistrarPoc> makeMoreRegistrarContacts(Registrar registrar) {
|
||||
static ImmutableList<RegistrarPoc> makeMoreRegistrarPocs(Registrar registrar) {
|
||||
return ImmutableList.of(
|
||||
new RegistrarPoc.Builder()
|
||||
.setRegistrar(registrar)
|
||||
@@ -365,88 +301,6 @@ class RdapJsonFormatterTest {
|
||||
.isEqualTo(loadJson("rdapjson_host_pending_transfer.json"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRegistrant() {
|
||||
assertAboutJson()
|
||||
.that(
|
||||
rdapJsonFormatter
|
||||
.createRdapContactEntity(
|
||||
contactRegistrant,
|
||||
ImmutableSet.of(RdapEntity.Role.REGISTRANT),
|
||||
OutputDataType.FULL)
|
||||
.toJson())
|
||||
.isEqualTo(loadJson("rdapjson_registrant.json"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRegistrant_summary() {
|
||||
assertAboutJson()
|
||||
.that(
|
||||
rdapJsonFormatter
|
||||
.createRdapContactEntity(
|
||||
contactRegistrant,
|
||||
ImmutableSet.of(RdapEntity.Role.REGISTRANT),
|
||||
OutputDataType.SUMMARY)
|
||||
.toJson())
|
||||
.isEqualTo(loadJson("rdapjson_registrant_summary.json"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRegistrant_loggedOut() {
|
||||
rdapJsonFormatter.rdapAuthorization = RdapAuthorization.PUBLIC_AUTHORIZATION;
|
||||
assertAboutJson()
|
||||
.that(
|
||||
rdapJsonFormatter
|
||||
.createRdapContactEntity(
|
||||
contactRegistrant,
|
||||
ImmutableSet.of(RdapEntity.Role.REGISTRANT),
|
||||
OutputDataType.FULL)
|
||||
.toJson())
|
||||
.isEqualTo(loadJson("rdapjson_registrant_logged_out.json"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAdmin() {
|
||||
assertAboutJson()
|
||||
.that(
|
||||
rdapJsonFormatter
|
||||
.createRdapContactEntity(
|
||||
contactAdmin, ImmutableSet.of(RdapEntity.Role.ADMIN), OutputDataType.FULL)
|
||||
.toJson())
|
||||
.isEqualTo(loadJson("rdapjson_admincontact.json"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTech() {
|
||||
assertAboutJson()
|
||||
.that(
|
||||
rdapJsonFormatter
|
||||
.createRdapContactEntity(
|
||||
contactTech, ImmutableSet.of(RdapEntity.Role.TECH), OutputDataType.FULL)
|
||||
.toJson())
|
||||
.isEqualTo(loadJson("rdapjson_techcontact.json"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRolelessContact() {
|
||||
assertAboutJson()
|
||||
.that(
|
||||
rdapJsonFormatter
|
||||
.createRdapContactEntity(contactTech, ImmutableSet.of(), OutputDataType.FULL)
|
||||
.toJson())
|
||||
.isEqualTo(loadJson("rdapjson_rolelesscontact.json"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUnlinkedContact() {
|
||||
assertAboutJson()
|
||||
.that(
|
||||
rdapJsonFormatter
|
||||
.createRdapContactEntity(contactNotLinked, ImmutableSet.of(), OutputDataType.FULL)
|
||||
.toJson())
|
||||
.isEqualTo(loadJson("rdapjson_unlinkedcontact.json"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDomain_full() {
|
||||
assertAboutJson()
|
||||
@@ -481,7 +335,7 @@ class RdapJsonFormatterTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDomain_noNameserversNoTransfersMultipleRoleContact() {
|
||||
void testDomain_noNameserversNoTransfers() {
|
||||
assertAboutJson()
|
||||
.that(
|
||||
rdapJsonFormatter
|
||||
|
||||
@@ -37,7 +37,6 @@ class RdapMetricsTest {
|
||||
RdapMetrics.responses.reset();
|
||||
RdapMetrics.numberOfDomainsRetrieved.reset();
|
||||
RdapMetrics.numberOfHostsRetrieved.reset();
|
||||
RdapMetrics.numberOfContactsRetrieved.reset();
|
||||
}
|
||||
|
||||
private RdapMetrics.RdapMetricInformation.Builder getBuilder() {
|
||||
@@ -188,7 +187,6 @@ class RdapMetricsTest {
|
||||
.and()
|
||||
.hasNoOtherValues();
|
||||
assertThat(RdapMetrics.numberOfHostsRetrieved).hasNoOtherValues();
|
||||
assertThat(RdapMetrics.numberOfContactsRetrieved).hasNoOtherValues();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -225,7 +223,6 @@ class RdapMetricsTest {
|
||||
ImmutableSet.of(10), "DOMAINS", "BY_NAMESERVER_NAME", "PREFIX_AND_SUFFIX", "2", "YES")
|
||||
.and()
|
||||
.hasNoOtherValues();
|
||||
assertThat(RdapMetrics.numberOfContactsRetrieved).hasNoOtherValues();
|
||||
}
|
||||
|
||||
/** Tests what would happen in a nameserver search for "*.cat.lol", which found no matches. */
|
||||
@@ -254,10 +251,8 @@ class RdapMetricsTest {
|
||||
ImmutableSet.of(0), "NAMESERVERS", "BY_NAMESERVER_NAME", "SUFFIX", "0", "NO")
|
||||
.and()
|
||||
.hasNoOtherValues();
|
||||
assertThat(RdapMetrics.numberOfContactsRetrieved).hasNoOtherValues();
|
||||
}
|
||||
|
||||
/** Tests what would happen in an entity search for "Mike*" which found 50 contacts. */
|
||||
@Test
|
||||
void testEntitySearchByNameWithWildcard() {
|
||||
rdapMetrics.updateMetrics(
|
||||
@@ -266,7 +261,6 @@ class RdapMetricsTest {
|
||||
.setSearchType(SearchType.BY_FULL_NAME)
|
||||
.setWildcardType(WildcardType.PREFIX)
|
||||
.setPrefixLength(4)
|
||||
.setNumContactsRetrieved(50)
|
||||
.build());
|
||||
assertThat(RdapMetrics.requests)
|
||||
.hasValueForLabels(1, "ENTITIES", "NO", "NO", "PUBLIC", "GET")
|
||||
@@ -279,10 +273,5 @@ class RdapMetricsTest {
|
||||
.hasNoOtherValues();
|
||||
assertThat(RdapMetrics.numberOfDomainsRetrieved).hasNoOtherValues();
|
||||
assertThat(RdapMetrics.numberOfHostsRetrieved).hasNoOtherValues();
|
||||
assertThat(RdapMetrics.numberOfContactsRetrieved)
|
||||
.hasDataSetForLabels(
|
||||
ImmutableSet.of(50), "ENTITIES", "BY_FULL_NAME", "PREFIX", "4", "NO")
|
||||
.and()
|
||||
.hasNoOtherValues();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,20 +131,7 @@ class RdapNameserverSearchActionTest extends RdapSearchActionTestCase<RdapNamese
|
||||
// create a domain so that we can use it as a test nameserver search string suffix
|
||||
domainCatLol =
|
||||
persistResource(
|
||||
makeDomain(
|
||||
"cat.lol",
|
||||
persistResource(
|
||||
FullFieldsTestEntityHelper.makeContact(
|
||||
"5372808-ERL", "Goblin Market", "lol@cat.lol", registrar)),
|
||||
persistResource(
|
||||
FullFieldsTestEntityHelper.makeContact(
|
||||
"5372808-IRL", "Santa Claus", "BOFH@cat.lol", registrar)),
|
||||
persistResource(
|
||||
FullFieldsTestEntityHelper.makeContact(
|
||||
"5372808-TRL", "The Raven", "bog@cat.lol", registrar)),
|
||||
hostNs1CatLol,
|
||||
hostNs2CatLol,
|
||||
registrar)
|
||||
makeDomain("cat.lol", null, null, null, hostNs1CatLol, hostNs2CatLol, registrar)
|
||||
.asBuilder()
|
||||
.setSubordinateHosts(ImmutableSet.of("ns1.cat.lol", "ns2.cat.lol"))
|
||||
.build());
|
||||
@@ -203,7 +190,6 @@ class RdapNameserverSearchActionTest extends RdapSearchActionTestCase<RdapNamese
|
||||
action.registrarParam.isPresent(),
|
||||
Optional.empty(),
|
||||
numHostsRetrieved,
|
||||
Optional.empty(),
|
||||
incompletenessWarningType);
|
||||
}
|
||||
|
||||
@@ -802,7 +788,7 @@ class RdapNameserverSearchActionTest extends RdapSearchActionTestCase<RdapNamese
|
||||
.that(generateActualJsonWithIp("5.5.5.1"))
|
||||
.isEqualTo(
|
||||
loadJsonFile(
|
||||
"rdap_truncated_hosts.json", "QUERY", "ip=5.5.5.1&cursor=MTctUk9JRA%3D%3D"));
|
||||
"rdap_truncated_hosts.json", "QUERY", "ip=5.5.5.1&cursor=MTQtUk9JRA%3D%3D"));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
verifyMetrics(5, IncompletenessWarningType.TRUNCATED);
|
||||
}
|
||||
@@ -814,7 +800,7 @@ class RdapNameserverSearchActionTest extends RdapSearchActionTestCase<RdapNamese
|
||||
.that(generateActualJsonWithIp("5.5.5.1"))
|
||||
.isEqualTo(
|
||||
loadJsonFile(
|
||||
"rdap_truncated_hosts.json", "QUERY", "ip=5.5.5.1&cursor=MTctUk9JRA%3D%3D"));
|
||||
"rdap_truncated_hosts.json", "QUERY", "ip=5.5.5.1&cursor=MTQtUk9JRA%3D%3D"));
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
// When searching by address and not including deleted, we don't need to search for extra
|
||||
// matches.
|
||||
|
||||
@@ -78,7 +78,6 @@ public abstract class RdapSearchActionTestCase<A extends RdapSearchActionBase>
|
||||
boolean registrarSpecified,
|
||||
Optional<Long> numDomainsRetrieved,
|
||||
Optional<Long> numHostsRetrieved,
|
||||
Optional<Long> numContactsRetrieved,
|
||||
IncompletenessWarningType incompletenessWarningType) {
|
||||
RdapMetrics.RdapMetricInformation.Builder builder =
|
||||
RdapMetrics.RdapMetricInformation.builder()
|
||||
@@ -94,7 +93,6 @@ public abstract class RdapSearchActionTestCase<A extends RdapSearchActionBase>
|
||||
.setIncompletenessWarningType(incompletenessWarningType);
|
||||
numDomainsRetrieved.ifPresent(builder::setNumDomainsRetrieved);
|
||||
numHostsRetrieved.ifPresent(builder::setNumHostsRetrieved);
|
||||
numContactsRetrieved.ifPresent(builder::setNumContactsRetrieved);
|
||||
verify(rdapMetrics).updateMetrics(builder.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,12 +39,6 @@ class RdapTestHelper {
|
||||
return GSON.fromJson(Joiner.on("\n").join(lines), JsonElement.class);
|
||||
}
|
||||
|
||||
enum ContactNoticeType {
|
||||
NONE,
|
||||
DOMAIN,
|
||||
CONTACT
|
||||
}
|
||||
|
||||
static RdapJsonFormatter getTestRdapJsonFormatter(Clock clock) {
|
||||
RdapJsonFormatter rdapJsonFormatter = new RdapJsonFormatter();
|
||||
rdapJsonFormatter.rdapAuthorization = RdapAuthorization.PUBLIC_AUTHORIZATION;
|
||||
|
||||
@@ -178,21 +178,56 @@ class CopyDetailReportsActionTest {
|
||||
verify(emailUtils)
|
||||
.sendAlertEmail(
|
||||
"""
|
||||
Copied detail reports.
|
||||
The following errors were encountered:
|
||||
Registrar: TheRegistrar
|
||||
Error: java.io.IOException: expected
|
||||
""");
|
||||
Copied detail reports.
|
||||
The following errors were encountered:
|
||||
Registrar: TheRegistrar
|
||||
Error: java.io.IOException: expected
|
||||
""");
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
assertThat(response.getContentType()).isEqualTo(MediaType.PLAIN_TEXT_UTF_8);
|
||||
assertThat(response.getPayload())
|
||||
.isEqualTo(
|
||||
"""
|
||||
Copied detail reports.
|
||||
The following errors were encountered:
|
||||
Registrar: TheRegistrar
|
||||
Error: java.io.IOException: expected
|
||||
""");
|
||||
Copied detail reports.
|
||||
The following errors were encountered:
|
||||
Registrar: TheRegistrar
|
||||
Error: java.io.IOException: expected
|
||||
""");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFail_tooManyFailures_one_registrar_sendsAlertEmail_continues() throws IOException {
|
||||
gcsUtils.createFromBytes(
|
||||
BlobId.of("test-bucket", "results/invoice_details_2017-10_TheRegistrar_hello.csv"),
|
||||
"hola,mundo\n3,4".getBytes(UTF_8));
|
||||
|
||||
gcsUtils.createFromBytes(
|
||||
BlobId.of("test-bucket", "results/invoice_details_2017-10_TheRegistrar_test.csv"),
|
||||
"hello,world\n1,2".getBytes(UTF_8));
|
||||
when(driveConnection.createOrUpdateFile(any(), any(), any(), any()))
|
||||
.thenThrow(new IOException("expected"));
|
||||
|
||||
action.run();
|
||||
verify(emailUtils)
|
||||
.sendAlertEmail(
|
||||
"""
|
||||
Copied detail reports.
|
||||
The following errors were encountered:
|
||||
Registrar: TheRegistrar
|
||||
Error: java.io.IOException: expected
|
||||
\tjava.io.IOException: expected
|
||||
""");
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
assertThat(response.getContentType()).isEqualTo(MediaType.PLAIN_TEXT_UTF_8);
|
||||
assertThat(response.getPayload())
|
||||
.isEqualTo(
|
||||
"""
|
||||
Copied detail reports.
|
||||
The following errors were encountered:
|
||||
Registrar: TheRegistrar
|
||||
Error: java.io.IOException: expected
|
||||
\tjava.io.IOException: expected
|
||||
""");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -26,10 +26,16 @@ import com.google.common.net.HostAndPort;
|
||||
import com.google.common.util.concurrent.SimpleTimeLimiter;
|
||||
import google.registry.util.RegistryEnvironment;
|
||||
import google.registry.util.UrlChecker;
|
||||
import jakarta.servlet.MultipartConfigElement;
|
||||
import jakarta.servlet.annotation.MultipartConfig;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.FutureTask;
|
||||
@@ -49,6 +55,8 @@ import org.eclipse.jetty.server.ServerConnector;
|
||||
* {@link #stop()} methods. However, a {@link #process()} method was added, which is used to process
|
||||
* requests made to servlets (not static files) in the calling thread.
|
||||
*
|
||||
* <p>A servlet that expects multi-part requests should be annotated with {@link MultipartConfig}.
|
||||
*
|
||||
* <p><b>Note:</b> This server is intended for development purposes. For the love all that is good,
|
||||
* do not make this public-facing.
|
||||
*
|
||||
@@ -70,6 +78,7 @@ public final class TestServer {
|
||||
private final HostAndPort urlAddress;
|
||||
private final Server server = new Server();
|
||||
private final BlockingQueue<FutureTask<Void>> requestQueue = new LinkedBlockingDeque<>();
|
||||
private List<Path> multiPartTmpDirs = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Creates a new instance, but does not begin serving.
|
||||
@@ -134,6 +143,13 @@ public final class TestServer {
|
||||
},
|
||||
SHUTDOWN_TIMEOUT_MS,
|
||||
TimeUnit.MILLISECONDS);
|
||||
for (var dir : multiPartTmpDirs) {
|
||||
try {
|
||||
Files.delete(dir);
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throwIfUnchecked(e);
|
||||
throw new RuntimeException(e);
|
||||
@@ -161,7 +177,27 @@ public final class TestServer {
|
||||
StaticResourceServlet.configureServletHolder(holder, runfile.getKey(), runfile.getValue());
|
||||
}
|
||||
for (Route route : routes) {
|
||||
context.addServlet(wrapServlet(route.servletClass()), route.path());
|
||||
holder = context.addServlet(wrapServlet(route.servletClass()), route.path());
|
||||
MultipartConfig multipartConfig = route.servletClass().getAnnotation(MultipartConfig.class);
|
||||
if (multipartConfig != null) {
|
||||
try {
|
||||
var location = multipartConfig.location();
|
||||
if (location == null || location.isBlank()) {
|
||||
Path tmpDir = Files.createTempDirectory("TestServer_");
|
||||
multiPartTmpDirs.add(tmpDir);
|
||||
location = tmpDir.toString();
|
||||
}
|
||||
MultipartConfigElement multipartConfigElement =
|
||||
new MultipartConfigElement(
|
||||
location,
|
||||
multipartConfig.maxFileSize(),
|
||||
multipartConfig.maxRequestSize(),
|
||||
multipartConfig.fileSizeThreshold());
|
||||
holder.getRegistration().setMultipartConfig(multipartConfigElement);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
holder = context.addServlet(DefaultServlet.class, "/*");
|
||||
holder.setInitParameter("aliases", "1");
|
||||
|
||||
@@ -587,7 +587,7 @@ public final class DatabaseHelper {
|
||||
public static Domain persistDomainWithDependentResources(
|
||||
String label,
|
||||
String tld,
|
||||
Contact contact,
|
||||
@Nullable Contact contact,
|
||||
DateTime now,
|
||||
DateTime creationTime,
|
||||
DateTime expirationTime) {
|
||||
@@ -601,13 +601,16 @@ public final class DatabaseHelper {
|
||||
.setCreationRegistrarId("TheRegistrar")
|
||||
.setCreationTimeForTest(creationTime)
|
||||
.setRegistrationExpirationTime(expirationTime)
|
||||
.setRegistrant(Optional.of(contact.createVKey()))
|
||||
.setContacts(
|
||||
ImmutableSet.of(
|
||||
DesignatedContact.create(Type.ADMIN, contact.createVKey()),
|
||||
DesignatedContact.create(Type.TECH, contact.createVKey())))
|
||||
.setAuthInfo(DomainAuthInfo.create(PasswordAuth.create("fooBAR")));
|
||||
Duration addGracePeriodLength = Tld.get(tld).getAddGracePeriodLength();
|
||||
if (contact != null) {
|
||||
domainBuilder
|
||||
.setRegistrant(Optional.of(contact.createVKey()))
|
||||
.setContacts(
|
||||
ImmutableSet.of(
|
||||
DesignatedContact.create(Type.ADMIN, contact.createVKey()),
|
||||
DesignatedContact.create(Type.TECH, contact.createVKey())));
|
||||
}
|
||||
if (creationTime.plus(addGracePeriodLength).isAfter(now)) {
|
||||
domainBuilder.addGracePeriod(
|
||||
GracePeriod.create(
|
||||
|
||||
@@ -50,10 +50,8 @@ class LoadTestCommandTest extends CommandTestCase<LoadTestCommand> {
|
||||
.put("clientId", "acme")
|
||||
.put("successfulHostCreates", 1)
|
||||
.put("successfulDomainCreates", 1)
|
||||
.put("successfulContactCreates", 1)
|
||||
.put("hostInfos", 1)
|
||||
.put("domainInfos", 1)
|
||||
.put("contactInfos", 1)
|
||||
.put("runSeconds", 9200)
|
||||
.build();
|
||||
verify(connection)
|
||||
@@ -69,10 +67,8 @@ class LoadTestCommandTest extends CommandTestCase<LoadTestCommand> {
|
||||
"--client_id=NewRegistrar",
|
||||
"--successful_host_creates=10",
|
||||
"--successful_domain_creates=11",
|
||||
"--successful_contact_creates=12",
|
||||
"--host_infos=13",
|
||||
"--domain_infos=14",
|
||||
"--contact_infos=15",
|
||||
"--run_seconds=16");
|
||||
ImmutableMap<String, Object> params =
|
||||
new ImmutableMap.Builder<String, Object>()
|
||||
@@ -80,10 +76,8 @@ class LoadTestCommandTest extends CommandTestCase<LoadTestCommand> {
|
||||
.put("clientId", "NewRegistrar")
|
||||
.put("successfulHostCreates", 10)
|
||||
.put("successfulDomainCreates", 11)
|
||||
.put("successfulContactCreates", 12)
|
||||
.put("hostInfos", 13)
|
||||
.put("domainInfos", 14)
|
||||
.put("contactInfos", 15)
|
||||
.put("runSeconds", 16)
|
||||
.build();
|
||||
verify(connection)
|
||||
|
||||
@@ -20,6 +20,7 @@ import static google.registry.testing.DatabaseHelper.loadRegistrar;
|
||||
import static google.registry.testing.DatabaseHelper.loadSingleton;
|
||||
import static google.registry.testing.SqlHelper.saveRegistrar;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
|
||||
import static jakarta.servlet.http.HttpServletResponse.SC_OK;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -54,30 +55,52 @@ class SecurityActionTest extends ConsoleActionBaseTestCase {
|
||||
SAMPLE_CERT2);
|
||||
private Registrar testRegistrar;
|
||||
|
||||
private static final String VALIDITY_TOO_LONG_CERT_PEM =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
+ "MIIDejCCAv+gAwIBAgIQHNcSEt4VENkSgtozEEoQLzAKBggqhkjOPQQDAzB8MQsw\n"
|
||||
+ "CQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0b24xGDAW\n"
|
||||
+ "BgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBSb290IENl\n"
|
||||
+ "cnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzAeFw0xOTAzMDcxOTQyNDJaFw0zNDAz\n"
|
||||
+ "MDMxOTQyNDJaMG8xCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UE\n"
|
||||
+ "BwwHSG91c3RvbjERMA8GA1UECgwIU1NMIENvcnAxKzApBgNVBAMMIlNTTC5jb20g\n"
|
||||
+ "U1NMIEludGVybWVkaWF0ZSBDQSBFQ0MgUjIwdjAQBgcqhkjOPQIBBgUrgQQAIgNi\n"
|
||||
+ "AASEOWn30uEYKDLFu4sCjFQ1VupFaeMtQjqVWyWSA7+KFljnsVaFQ2hgs4cQk1f/\n"
|
||||
+ "RQ2INSwdVCYU0i5qsbom20rigUhDh9dM/r6bEZ75eFE899kSCI14xqThYVLPdLEl\n"
|
||||
+ "+dyjggFRMIIBTTASBgNVHRMBAf8ECDAGAQH/AgEAMB8GA1UdIwQYMBaAFILRhXMw\n"
|
||||
+ "5zUE044CkvvlpNHEIejNMHgGCCsGAQUFBwEBBGwwajBGBggrBgEFBQcwAoY6aHR0\n"
|
||||
+ "cDovL3d3dy5zc2wuY29tL3JlcG9zaXRvcnkvU1NMY29tLVJvb3RDQS1FQ0MtMzg0\n"
|
||||
+ "LVIxLmNydDAgBggrBgEFBQcwAYYUaHR0cDovL29jc3BzLnNzbC5jb20wEQYDVR0g\n"
|
||||
+ "BAowCDAGBgRVHSAAMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATA7BgNV\n"
|
||||
+ "HR8ENDAyMDCgLqAshipodHRwOi8vY3Jscy5zc2wuY29tL3NzbC5jb20tZWNjLVJv\n"
|
||||
+ "b3RDQS5jcmwwHQYDVR0OBBYEFA10Zgpen+Is7NXCXSUEf3Uyuv99MA4GA1UdDwEB\n"
|
||||
+ "/wQEAwIBhjAKBggqhkjOPQQDAwNpADBmAjEAxYt6Ylk/N8Fch/3fgKYKwI5A011Q\n"
|
||||
+ "MKW0h3F9JW/NX/F7oYtWrxljheH8n2BrkDybAjEAlCxkLE0vQTYcFzrR24oogyw6\n"
|
||||
+ "VkgTm92+jiqJTO5SSA9QUa092S5cTKiHkH2cOM6m\n"
|
||||
+ "-----END CERTIFICATE-----";
|
||||
|
||||
private AuthenticatedRegistrarAccessor registrarAccessor =
|
||||
AuthenticatedRegistrarAccessor.createForTesting(
|
||||
ImmutableSetMultimap.of("registrarId", AuthenticatedRegistrarAccessor.Role.ADMIN));
|
||||
|
||||
private CertificateChecker certificateChecker =
|
||||
new CertificateChecker(
|
||||
ImmutableSortedMap.of(START_OF_TIME, 20825, DateTime.parse("2020-09-01T00:00:00Z"), 398),
|
||||
30,
|
||||
15,
|
||||
2048,
|
||||
ImmutableSet.of("secp256r1", "secp384r1"),
|
||||
clock);
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
testRegistrar = saveRegistrar("registrarId");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_postRegistrarInfo() throws IOException {
|
||||
CertificateChecker lenientChecker =
|
||||
new CertificateChecker(
|
||||
ImmutableSortedMap.of(
|
||||
START_OF_TIME, 20825, DateTime.parse("2020-09-01T00:00:00Z"), 398),
|
||||
30,
|
||||
15,
|
||||
2048,
|
||||
ImmutableSet.of("secp256r1", "secp384r1"),
|
||||
clock);
|
||||
|
||||
clock.setTo(DateTime.parse("2020-11-01T00:00:00Z"));
|
||||
SecurityAction action =
|
||||
createAction(
|
||||
testRegistrar.getRegistrarId());
|
||||
SecurityAction action = createAction(testRegistrar.getRegistrarId(), lenientChecker);
|
||||
action.run();
|
||||
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_OK);
|
||||
Registrar r = loadRegistrar(testRegistrar.getRegistrarId());
|
||||
@@ -90,9 +113,39 @@ class SecurityActionTest extends ConsoleActionBaseTestCase {
|
||||
assertThat(history.getDescription()).hasValue("registrarId|IP_CHANGE,PRIMARY_SSL_CERT_CHANGE");
|
||||
}
|
||||
|
||||
private SecurityAction createAction(String registrarId) throws IOException {
|
||||
@Test
|
||||
void testFailure_validityPeriodTooLong_returnsSpecificError() throws IOException {
|
||||
CertificateChecker strictChecker =
|
||||
new CertificateChecker(
|
||||
ImmutableSortedMap.of(START_OF_TIME, 398),
|
||||
30,
|
||||
15,
|
||||
2048,
|
||||
ImmutableSet.of("secp256r1", "secp384r1"),
|
||||
clock);
|
||||
|
||||
clock.setTo(DateTime.parse("2025-01-01T00:00:00Z"));
|
||||
String escapedCert = VALIDITY_TOO_LONG_CERT_PEM.replace("\n", "\\n");
|
||||
String jsonWithBadCert =
|
||||
String.format(
|
||||
"{\"registrarId\": \"registrarId\", \"clientCertificate\": \"%s\"}", escapedCert);
|
||||
|
||||
SecurityAction action =
|
||||
createAction(testRegistrar.getRegistrarId(), jsonWithBadCert, strictChecker);
|
||||
action.run();
|
||||
|
||||
String expectedError =
|
||||
"Certificate validity period is too long; it must be less than or equal to 398 days.";
|
||||
FakeResponse response = (FakeResponse) consoleApiParams.response();
|
||||
assertThat(response.getStatus()).isEqualTo(SC_BAD_REQUEST);
|
||||
assertThat(response.getPayload()).isEqualTo(expectedError);
|
||||
}
|
||||
|
||||
private SecurityAction createAction(
|
||||
String registrarId, String jsonBody, CertificateChecker certificateChecker)
|
||||
throws IOException {
|
||||
when(consoleApiParams.request().getMethod()).thenReturn(Action.Method.POST.toString());
|
||||
doReturn(new BufferedReader(new StringReader(jsonRegistrar1)))
|
||||
doReturn(new BufferedReader(new StringReader(jsonBody)))
|
||||
.when(consoleApiParams.request())
|
||||
.getReader();
|
||||
Optional<Registrar> maybeRegistrar =
|
||||
@@ -101,4 +154,9 @@ class SecurityActionTest extends ConsoleActionBaseTestCase {
|
||||
return new SecurityAction(
|
||||
consoleApiParams, certificateChecker, registrarAccessor, registrarId, maybeRegistrar);
|
||||
}
|
||||
|
||||
private SecurityAction createAction(String registrarId, CertificateChecker certificateChecker)
|
||||
throws IOException {
|
||||
return createAction(registrarId, jsonRegistrar1, certificateChecker);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,11 +21,11 @@ import static org.apache.commons.text.StringEscapeUtils.escapeEcmaScript;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Predicates;
|
||||
import java.net.URL;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Predicate;
|
||||
import org.junit.jupiter.api.extension.AfterEachCallback;
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
@@ -100,7 +100,7 @@ public final class WebDriverPlusScreenDifferExtension
|
||||
webDriverPlusScreenDiffer =
|
||||
new WebDriverScreenDiffer(driver, GOLDENS_PATH, MAX_COLOR_DIFF, MAX_PIXEL_DIFF);
|
||||
// non-zero timeout so findByElement will wait for the element to appear
|
||||
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
|
||||
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
|
||||
driver.manage().window().setSize(DEFAULT_WINDOW_SIZE);
|
||||
|
||||
if (imageNamePrefix == null) {
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
{
|
||||
"rdapConformance": [
|
||||
"rdap_level_0",
|
||||
"icann_rdap_response_profile_1",
|
||||
"icann_rdap_technical_implementation_guide_1"
|
||||
],
|
||||
"objectClassName": "entity",
|
||||
"handle": "%CONTACT_HANDLE_1%",
|
||||
"status": ["active", "associated"],
|
||||
"links": [
|
||||
{
|
||||
"rel": "self",
|
||||
"href": "https://example.tld/rdap/entity/%CONTACT_HANDLE_1%",
|
||||
"type": "application/rdap+json",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
{
|
||||
"eventAction": "last update of RDAP database",
|
||||
"eventDate": "2000-01-01T00:00:00.000Z"
|
||||
}
|
||||
],
|
||||
"vcardArray":
|
||||
[
|
||||
"vcard",
|
||||
[
|
||||
["version", {}, "text", "4.0"],
|
||||
["fn", {}, "text", "%CONTACT_FULLNAME_1%"],
|
||||
["org", {}, "text", "GOOGLE INCORPORATED <script>"],
|
||||
["adr", {}, "text",
|
||||
[
|
||||
"",
|
||||
"",
|
||||
[ %CONTACT_ADDRESS_1% ],
|
||||
"KOKOMO",
|
||||
"BM",
|
||||
"31337",
|
||||
"United States"
|
||||
]
|
||||
],
|
||||
["tel", {"type": ["voice"]}, "uri", "tel:+1.2126660420"],
|
||||
["tel", {"type": ["fax"]}, "uri", "tel:+1.2126660420"]
|
||||
]
|
||||
],
|
||||
"remarks": [
|
||||
{
|
||||
"title": "EMAIL REDACTED FOR PRIVACY",
|
||||
"type": "object redacted due to authorization",
|
||||
"description": [
|
||||
"Please query the RDDS service of the Registrar of Record identifies in this output for information on how to contact the Registrant of the queried domain name."
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
{
|
||||
"rdapConformance": [
|
||||
"rdap_level_0",
|
||||
"icann_rdap_response_profile_1",
|
||||
"icann_rdap_technical_implementation_guide_1"
|
||||
],
|
||||
"objectClassName" : "entity",
|
||||
"handle" : "",
|
||||
"events": [
|
||||
{
|
||||
"eventAction": "last update of RDAP database",
|
||||
"eventDate": "2000-01-01T00:00:00.000Z"
|
||||
}
|
||||
],
|
||||
"vcardArray": [
|
||||
"vcard",
|
||||
[
|
||||
["version", {}, "text", "4.0"],
|
||||
["fn", {}, "text", ""]
|
||||
]
|
||||
],
|
||||
"remarks": [
|
||||
{
|
||||
"title": "REDACTED FOR PRIVACY",
|
||||
"type": "object redacted due to authorization",
|
||||
"links": [
|
||||
{
|
||||
"type":"text\/html",
|
||||
"href": "https:\/\/github.com\/google\/nomulus\/blob\/master\/docs\/rdap.md#authentication",
|
||||
"rel": "alternate",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
"Some of the data in this object has been removed.",
|
||||
"Contact personal data is visible only to the owning registrar."
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "EMAIL REDACTED FOR PRIVACY",
|
||||
"type": "object redacted due to authorization",
|
||||
"description": [
|
||||
"Please query the RDDS service of the Registrar of Record identifies in this output for information on how to contact the Registrant of the queried domain name."
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
{
|
||||
"rdapConformance": [
|
||||
"rdap_level_0",
|
||||
"icann_rdap_response_profile_1",
|
||||
"icann_rdap_technical_implementation_guide_1"
|
||||
],
|
||||
"objectClassName" : "entity",
|
||||
"handle" : "%CONTACT_HANDLE_1%",
|
||||
"status" : ["%STATUS_1%"],
|
||||
"links" :
|
||||
[
|
||||
{
|
||||
"rel" : "self",
|
||||
"href": "https://example.tld/rdap/entity/%CONTACT_HANDLE_1%",
|
||||
"type" : "application/rdap+json",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
{
|
||||
"eventAction": "last update of RDAP database",
|
||||
"eventDate": "2000-01-01T00:00:00.000Z"
|
||||
}
|
||||
],
|
||||
"vcardArray" :
|
||||
[
|
||||
"vcard",
|
||||
[
|
||||
["version", {}, "text", "4.0"],
|
||||
["fn", {}, "text", "%CONTACT_FULLNAME_1%"],
|
||||
["org", {}, "text", "GOOGLE INCORPORATED <script>"],
|
||||
["adr", {}, "text",
|
||||
[
|
||||
"",
|
||||
"",
|
||||
[ %CONTACT_ADDRESS_1% ],
|
||||
"KOKOMO",
|
||||
"BM",
|
||||
"31337",
|
||||
"United States"
|
||||
]
|
||||
],
|
||||
["tel", {"type" : ["voice"]}, "uri", "tel:+1.2126660420"],
|
||||
["tel", {"type" : ["fax"]}, "uri", "tel:+1.2126660420"]
|
||||
]
|
||||
],
|
||||
"remarks": [
|
||||
{
|
||||
"title": "EMAIL REDACTED FOR PRIVACY",
|
||||
"type": "object redacted due to authorization",
|
||||
"description": [
|
||||
"Please query the RDDS service of the Registrar of Record identifies in this output for information on how to contact the Registrant of the queried domain name."
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
{
|
||||
"rdapConformance": [
|
||||
"rdap_level_0",
|
||||
"icann_rdap_response_profile_1",
|
||||
"icann_rdap_technical_implementation_guide_1"
|
||||
],
|
||||
"objectClassName" : "entity",
|
||||
"handle" : "%CONTACT_HANDLE_1%",
|
||||
"status" : ["inactive"],
|
||||
"links" :
|
||||
[
|
||||
{
|
||||
"rel" : "self",
|
||||
"href": "https://example.tld/rdap/entity/%CONTACT_HANDLE_1%",
|
||||
"type" : "application/rdap+json",
|
||||
"value": "%REQUEST_URL%"
|
||||
}
|
||||
],
|
||||
"events":
|
||||
[
|
||||
{
|
||||
"eventAction": "last update of RDAP database",
|
||||
"eventDate": "2000-01-01T00:00:00.000Z"
|
||||
}
|
||||
],
|
||||
"vcardArray" :
|
||||
[
|
||||
"vcard",
|
||||
[
|
||||
["version", {}, "text", "4.0"]
|
||||
]
|
||||
],
|
||||
"remarks": [
|
||||
{
|
||||
"title": "EMAIL REDACTED FOR PRIVACY",
|
||||
"type": "object redacted due to authorization",
|
||||
"description": [
|
||||
"Please query the RDDS service of the Registrar of Record identifies in this output for information on how to contact the Registrant of the queried domain name."
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user