mirror of
https://github.com/google/nomulus
synced 2026-05-20 23:01:53 +00:00
Compare commits
19 Commits
nomulus-20
...
nomulus-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e82cbe60a9 | ||
|
|
923bc13e3a | ||
|
|
4893ea307b | ||
|
|
01f868cefc | ||
|
|
1b0919eaff | ||
|
|
92b23bac16 | ||
|
|
cc9b3f5965 | ||
|
|
dd86c56ddc | ||
|
|
08551f7bc7 | ||
|
|
e7171a326b | ||
|
|
c3eae7b76f | ||
|
|
2687181045 | ||
|
|
68750569db | ||
|
|
028e5cc958 | ||
|
|
853e571d01 | ||
|
|
9b79f5af2c | ||
|
|
4195871541 | ||
|
|
504d7ccaac | ||
|
|
36a8908712 |
@@ -28,6 +28,7 @@ import ContactComponent from './settings/contact/contact.component';
|
||||
import WhoisComponent from './settings/whois/whois.component';
|
||||
import SecurityComponent from './settings/security/security.component';
|
||||
import UsersComponent from './settings/users/users.component';
|
||||
import { DomainListComponent } from './domains/domainList.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', redirectTo: '/home', pathMatch: 'full' },
|
||||
@@ -35,6 +36,11 @@ const routes: Routes = [
|
||||
{ path: 'empty-registrar', component: EmptyRegistrar },
|
||||
{ path: 'home', component: HomeComponent, canActivate: [RegistrarGuard] },
|
||||
{ path: 'tlds', component: TldsComponent, canActivate: [RegistrarGuard] },
|
||||
{
|
||||
path: DomainListComponent.PATH,
|
||||
component: DomainListComponent,
|
||||
canActivate: [RegistrarGuard],
|
||||
},
|
||||
{
|
||||
path: SettingsComponent.PATH,
|
||||
component: SettingsComponent,
|
||||
|
||||
@@ -36,16 +36,16 @@ import { RegistrarGuard } from './registrar/registrar.guard';
|
||||
import SecurityComponent from './settings/security/security.component';
|
||||
import { MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';
|
||||
import { EmptyRegistrar } from './registrar/emptyRegistrar.component';
|
||||
import { RegistrarSelectorComponent } from './registrar/registrar-selector.component';
|
||||
import { RegistrarSelectorComponent } from './registrar/registrarSelector.component';
|
||||
import { GlobalLoaderService } from './shared/services/globalLoader.service';
|
||||
import { ContactWidgetComponent } from './home/widgets/contact-widget.component';
|
||||
import { PromotionsWidgetComponent } from './home/widgets/promotions-widget.component';
|
||||
import { TldsWidgetComponent } from './home/widgets/tlds-widget.component';
|
||||
import { ResourcesWidgetComponent } from './home/widgets/resources-widget.component';
|
||||
import { EppWidgetComponent } from './home/widgets/epp-widget.component';
|
||||
import { BillingWidgetComponent } from './home/widgets/billing-widget.component';
|
||||
import { DomainsWidgetComponent } from './home/widgets/domains-widget.component';
|
||||
import { SettingsWidgetComponent } from './home/widgets/settings-widget.component';
|
||||
import { ContactWidgetComponent } from './home/widgets/contactWidget.component';
|
||||
import { PromotionsWidgetComponent } from './home/widgets/promotionsWidget.component';
|
||||
import { TldsWidgetComponent } from './home/widgets/tldsWidget.component';
|
||||
import { ResourcesWidgetComponent } from './home/widgets/resourcesWidget.component';
|
||||
import { EppWidgetComponent } from './home/widgets/eppWidget.component';
|
||||
import { BillingWidgetComponent } from './home/widgets/billingWidget.component';
|
||||
import { DomainsWidgetComponent } from './home/widgets/domainsWidget.component';
|
||||
import { SettingsWidgetComponent } from './home/widgets/settingsWidget.component';
|
||||
import { UserDataService } from './shared/services/userData.service';
|
||||
import WhoisComponent from './settings/whois/whois.component';
|
||||
import { SnackBarModule } from './snackbar.module';
|
||||
@@ -53,6 +53,7 @@ import {
|
||||
RegistrarDetailsComponent,
|
||||
RegistrarDetailsWrapperComponent,
|
||||
} from './registrar/registrarDetails.component';
|
||||
import { DomainListComponent } from './domains/domainList.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@@ -60,6 +61,7 @@ import {
|
||||
BillingWidgetComponent,
|
||||
ContactDetailsDialogComponent,
|
||||
ContactWidgetComponent,
|
||||
DomainListComponent,
|
||||
DomainsWidgetComponent,
|
||||
EmptyRegistrar,
|
||||
EppWidgetComponent,
|
||||
|
||||
54
console-webapp/src/app/domains/domainList.component.html
Normal file
54
console-webapp/src/app/domains/domainList.component.html
Normal file
@@ -0,0 +1,54 @@
|
||||
<div class="console-domains">
|
||||
<mat-form-field>
|
||||
<mat-label>Filter</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event)" #input />
|
||||
</mat-form-field>
|
||||
|
||||
<div *ngIf="isLoading; else domains_content" class="console-domains__loading">
|
||||
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
||||
</div>
|
||||
<ng-template #domains_content>
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
|
||||
<ng-container matColumnDef="domainName">
|
||||
<th mat-header-cell *matHeaderCellDef>Domain Name</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.domainName }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="creationTime">
|
||||
<th mat-header-cell *matHeaderCellDef>Creation Time</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
{{ element.creationTime.creationTime }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="registrationExpirationTime">
|
||||
<th mat-header-cell *matHeaderCellDef>Expiration Time</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
{{ element.registrationExpirationTime }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="statuses">
|
||||
<th mat-header-cell *matHeaderCellDef>Statuses</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.statuses }}</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
|
||||
<!-- Row shown when there is no matching data. -->
|
||||
<tr class="mat-row" *matNoDataRow>
|
||||
<td class="mat-cell" colspan="4">No domains found</td>
|
||||
</tr>
|
||||
</table>
|
||||
<mat-paginator
|
||||
[length]="totalResults"
|
||||
[pageIndex]="pageNumber"
|
||||
[pageSize]="resultsPerPage"
|
||||
[pageSizeOptions]="[10, 25, 50, 100, 500]"
|
||||
(page)="onPageChange($event)"
|
||||
aria-label="Select page of domain results"
|
||||
showFirstLastButtons
|
||||
></mat-paginator>
|
||||
</ng-template>
|
||||
</div>
|
||||
36
console-webapp/src/app/domains/domainList.component.spec.ts
Normal file
36
console-webapp/src/app/domains/domainList.component.spec.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright 2023 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DomainListComponent } from './domainList.component';
|
||||
|
||||
describe('DomainListComponent', () => {
|
||||
let component: DomainListComponent;
|
||||
let fixture: ComponentFixture<DomainListComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [DomainListComponent],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(DomainListComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
80
console-webapp/src/app/domains/domainList.component.ts
Normal file
80
console-webapp/src/app/domains/domainList.component.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright 2023 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, ViewChild } from '@angular/core';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { BackendService } from '../shared/services/backend.service';
|
||||
import { MatPaginator, PageEvent } from '@angular/material/paginator';
|
||||
import { RegistrarService } from '../registrar/registrar.service';
|
||||
import { Domain, DomainListService } from './domainList.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-domain-list',
|
||||
templateUrl: './domainList.component.html',
|
||||
styleUrls: ['./domainList.component.scss'],
|
||||
providers: [DomainListService],
|
||||
})
|
||||
export class DomainListComponent {
|
||||
public static PATH = 'domain-list';
|
||||
|
||||
displayedColumns: string[] = [
|
||||
'domainName',
|
||||
'creationTime',
|
||||
'registrationExpirationTime',
|
||||
'statuses',
|
||||
];
|
||||
|
||||
dataSource: MatTableDataSource<Domain> = new MatTableDataSource();
|
||||
isLoading = true;
|
||||
|
||||
pageNumber?: number;
|
||||
resultsPerPage = 50;
|
||||
totalResults?: number;
|
||||
|
||||
@ViewChild(MatPaginator, { static: true }) paginator!: MatPaginator;
|
||||
|
||||
constructor(
|
||||
private backendService: BackendService,
|
||||
private domainListService: DomainListService,
|
||||
private registrarService: RegistrarService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.dataSource.paginator = this.paginator;
|
||||
this.reloadData();
|
||||
}
|
||||
|
||||
reloadData() {
|
||||
this.isLoading = true;
|
||||
this.domainListService
|
||||
.retrieveDomains(this.pageNumber, this.resultsPerPage, this.totalResults)
|
||||
.subscribe((domainListResult) => {
|
||||
this.dataSource.data = domainListResult.domains;
|
||||
this.totalResults = domainListResult.totalResults;
|
||||
this.isLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
/** TODO: the backend will need to accept a filter string. */
|
||||
applyFilter(event: KeyboardEvent) {
|
||||
// const filterValue = (event.target as HTMLInputElement).value;
|
||||
this.reloadData();
|
||||
}
|
||||
|
||||
onPageChange(event: PageEvent) {
|
||||
this.pageNumber = event.pageIndex;
|
||||
this.resultsPerPage = event.pageSize;
|
||||
this.reloadData();
|
||||
}
|
||||
}
|
||||
66
console-webapp/src/app/domains/domainList.service.ts
Normal file
66
console-webapp/src/app/domains/domainList.service.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
// Copyright 2023 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { BackendService } from '../shared/services/backend.service';
|
||||
import { RegistrarService } from '../registrar/registrar.service';
|
||||
import { tap } from 'rxjs';
|
||||
|
||||
export interface CreateAutoTimestamp {
|
||||
creationTime: string;
|
||||
}
|
||||
|
||||
export interface Domain {
|
||||
creationTime: CreateAutoTimestamp;
|
||||
currentSponsorRegistrarId: string;
|
||||
domainName: string;
|
||||
registrationExpirationTime: string;
|
||||
statuses: string[];
|
||||
}
|
||||
|
||||
export interface DomainListResult {
|
||||
checkpointTime: string;
|
||||
domains: Domain[];
|
||||
totalResults: number;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class DomainListService {
|
||||
checkpointTime?: string;
|
||||
|
||||
constructor(
|
||||
private backendService: BackendService,
|
||||
private registrarService: RegistrarService
|
||||
) {}
|
||||
|
||||
retrieveDomains(
|
||||
pageNumber?: number,
|
||||
resultsPerPage?: number,
|
||||
totalResults?: number
|
||||
) {
|
||||
return this.backendService
|
||||
.getDomains(
|
||||
this.registrarService.activeRegistrarId,
|
||||
this.checkpointTime,
|
||||
pageNumber,
|
||||
resultsPerPage,
|
||||
totalResults
|
||||
)
|
||||
.pipe(
|
||||
tap((domainListResult: DomainListResult) => {
|
||||
this.checkpointTime = domainListResult.checkpointTime;
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ import { RegistrarService } from 'src/app/registrar/registrar.service';
|
||||
|
||||
@Component({
|
||||
selector: '[app-billing-widget]',
|
||||
templateUrl: './billing-widget.component.html',
|
||||
templateUrl: './billingWidget.component.html',
|
||||
})
|
||||
export class BillingWidgetComponent {
|
||||
constructor(public registrarService: RegistrarService) {}
|
||||
@@ -17,7 +17,7 @@ import { UserDataService } from 'src/app/shared/services/userData.service';
|
||||
|
||||
@Component({
|
||||
selector: '[app-contact-widget]',
|
||||
templateUrl: './contact-widget.component.html',
|
||||
templateUrl: './contactWidget.component.html',
|
||||
})
|
||||
export class ContactWidgetComponent {
|
||||
constructor(public userDataService: UserDataService) {}
|
||||
@@ -13,7 +13,12 @@
|
||||
Create a Domain
|
||||
</button>
|
||||
<p class="secondary-text">Register a new domain name</p>
|
||||
<button mat-button color="primary" class="console-app__widget-link">
|
||||
<button
|
||||
mat-button
|
||||
color="primary"
|
||||
class="console-app__widget-link"
|
||||
(click)="openDomainsPage()"
|
||||
>
|
||||
View DUMs
|
||||
</button>
|
||||
<p class="secondary-text">
|
||||
@@ -13,11 +13,17 @@
|
||||
// limitations under the License.
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { DomainListComponent } from 'src/app/domains/domainList.component';
|
||||
|
||||
@Component({
|
||||
selector: '[app-domains-widget]',
|
||||
templateUrl: './domains-widget.component.html',
|
||||
templateUrl: './domainsWidget.component.html',
|
||||
})
|
||||
export class DomainsWidgetComponent {
|
||||
constructor() {}
|
||||
constructor(private router: Router) {}
|
||||
|
||||
openDomainsPage() {
|
||||
this.router.navigate([DomainListComponent.PATH]);
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: '[app-epp-widget]',
|
||||
templateUrl: './epp-widget.component.html',
|
||||
templateUrl: './eppWidget.component.html',
|
||||
})
|
||||
export class EppWidgetComponent {
|
||||
constructor() {}
|
||||
@@ -16,7 +16,7 @@ import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: '[app-promotions-widget]',
|
||||
templateUrl: './promotions-widget.component.html',
|
||||
templateUrl: './promotionsWidget.component.html',
|
||||
})
|
||||
export class PromotionsWidgetComponent {
|
||||
constructor() {}
|
||||
@@ -17,7 +17,7 @@ import { UserDataService } from 'src/app/shared/services/userData.service';
|
||||
|
||||
@Component({
|
||||
selector: '[app-resources-widget]',
|
||||
templateUrl: './resources-widget.component.html',
|
||||
templateUrl: './resourcesWidget.component.html',
|
||||
})
|
||||
export class ResourcesWidgetComponent {
|
||||
constructor(public userDataService: UserDataService) {}
|
||||
@@ -21,7 +21,7 @@ import { SettingsComponent } from 'src/app/settings/settings.component';
|
||||
|
||||
@Component({
|
||||
selector: '[app-settings-widget]',
|
||||
templateUrl: './settings-widget.component.html',
|
||||
templateUrl: './settingsWidget.component.html',
|
||||
})
|
||||
export class SettingsWidgetComponent {
|
||||
constructor(private router: Router) {}
|
||||
@@ -16,7 +16,7 @@ import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: '[app-tlds-widget]',
|
||||
templateUrl: './tlds-widget.component.html',
|
||||
templateUrl: './tldsWidget.component.html',
|
||||
})
|
||||
export class TldsWidgetComponent {
|
||||
constructor() {}
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { RegistrarSelectorComponent } from './registrar-selector.component';
|
||||
import { RegistrarSelectorComponent } from './registrarSelector.component';
|
||||
|
||||
describe('RegistrarSelectorComponent', () => {
|
||||
let component: RegistrarSelectorComponent;
|
||||
@@ -21,8 +21,8 @@ const MOBILE_LAYOUT_BREAKPOINT = '(max-width: 599px)';
|
||||
|
||||
@Component({
|
||||
selector: 'app-registrar-selector',
|
||||
templateUrl: './registrar-selector.component.html',
|
||||
styleUrls: ['./registrar-selector.component.scss'],
|
||||
templateUrl: './registrarSelector.component.html',
|
||||
styleUrls: ['./registrarSelector.component.scss'],
|
||||
})
|
||||
export class RegistrarSelectorComponent implements OnInit {
|
||||
protected isMobile: boolean = false;
|
||||
@@ -76,7 +76,7 @@ class ContactDetailsEventsResponder {
|
||||
|
||||
@Component({
|
||||
selector: 'app-contact-details-dialog',
|
||||
templateUrl: 'contact-details.component.html',
|
||||
templateUrl: 'contactDetails.component.html',
|
||||
styleUrls: ['./contact.component.scss'],
|
||||
})
|
||||
export class ContactDetailsDialogComponent {
|
||||
|
||||
@@ -21,6 +21,7 @@ import { Contact } from '../../settings/contact/contact.service';
|
||||
import { Registrar } from '../../registrar/registrar.service';
|
||||
import { UserData } from './userData.service';
|
||||
import { WhoisRegistrarFields } from 'src/app/settings/whois/whois.service';
|
||||
import { DomainListResult } from 'src/app/domains/domainList.service';
|
||||
|
||||
@Injectable()
|
||||
export class BackendService {
|
||||
@@ -63,6 +64,31 @@ export class BackendService {
|
||||
);
|
||||
}
|
||||
|
||||
getDomains(
|
||||
registrarId: string,
|
||||
checkpointTime?: string,
|
||||
pageNumber?: number,
|
||||
resultsPerPage?: number,
|
||||
totalResults?: number
|
||||
): Observable<DomainListResult> {
|
||||
var url = `/console-api/domain-list?registrarId=${registrarId}`;
|
||||
if (checkpointTime) {
|
||||
url += `&checkpointTime=${checkpointTime}`;
|
||||
}
|
||||
if (pageNumber) {
|
||||
url += `&pageNumber=${pageNumber}`;
|
||||
}
|
||||
if (resultsPerPage) {
|
||||
url += `&resultsPerPage=${resultsPerPage}`;
|
||||
}
|
||||
if (totalResults) {
|
||||
url += `&totalResults=${totalResults}`;
|
||||
}
|
||||
return this.http
|
||||
.get<DomainListResult>(url)
|
||||
.pipe(catchError((err) => this.errorCatcher<DomainListResult>(err)));
|
||||
}
|
||||
|
||||
getRegistrars(): Observable<Registrar[]> {
|
||||
return this.http
|
||||
.get<Registrar[]>('/console-api/registrars')
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
@use "@angular/material" as mat;
|
||||
@import "app/registrar/registrar-selector.component.scss";
|
||||
@import "app/registrar/registrarSelector.component.scss";
|
||||
|
||||
html,
|
||||
body {
|
||||
|
||||
@@ -16,8 +16,8 @@ package google.registry.bsa;
|
||||
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static com.google.common.collect.Maps.transformValues;
|
||||
import static google.registry.model.tld.Tld.isEnrolledWithBsa;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
@@ -50,14 +50,6 @@ public class IdnChecker {
|
||||
allTlds = idnToTlds.values().stream().flatMap(ImmutableSet::stream).collect(toImmutableSet());
|
||||
}
|
||||
|
||||
// TODO(11/30/2023): Remove below when new Tld schema is deployed and the `getBsaEnrollStartTime`
|
||||
// method is no longer hardcoded.
|
||||
@VisibleForTesting
|
||||
IdnChecker(ImmutableMap<IdnTableEnum, ImmutableSet<Tld>> idnToTlds) {
|
||||
this.idnToTlds = idnToTlds;
|
||||
allTlds = idnToTlds.values().stream().flatMap(ImmutableSet::stream).collect(toImmutableSet());
|
||||
}
|
||||
|
||||
/** Returns all IDNs in which the {@code label} is valid. */
|
||||
ImmutableSet<IdnTableEnum> getAllValidIdns(String label) {
|
||||
return idnToTlds.keySet().stream()
|
||||
@@ -88,11 +80,6 @@ public class IdnChecker {
|
||||
return Sets.difference(allTlds, getSupportingTlds(idnTables));
|
||||
}
|
||||
|
||||
private static boolean isEnrolledWithBsa(Tld tld, DateTime now) {
|
||||
DateTime enrollTime = tld.getBsaEnrollStartTime();
|
||||
return enrollTime != null && enrollTime.isBefore(now);
|
||||
}
|
||||
|
||||
private static ImmutableMap<IdnTableEnum, ImmutableSet<Tld>> getIdnToTldMap(DateTime now) {
|
||||
ImmutableMultimap.Builder<IdnTableEnum, Tld> idnToTldMap = new ImmutableMultimap.Builder();
|
||||
Tlds.getTldEntitiesOfType(TldType.REAL).stream()
|
||||
|
||||
@@ -1397,6 +1397,47 @@ public final class RegistryConfig {
|
||||
return config.bulkPricingPackageMonitoring.bulkPricingPackageDomainLimitUpgradeEmailBody;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Config("bsaGcsBucket")
|
||||
public static String provideBsaGcsBucket(@Config("projectId") String projectId) {
|
||||
return projectId + "-bsa";
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Config("bsaChecksumAlgorithm")
|
||||
public static String provideBsaChecksumAlgorithm(RegistryConfigSettings config) {
|
||||
return config.bsa.bsaChecksumAlgorithm;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Config("bsaLockLeaseExpiry")
|
||||
public static Duration provideBsaLockLeaseExpiry(RegistryConfigSettings config) {
|
||||
return Duration.standardMinutes(config.bsa.bsaLockLeaseExpiryMinutes);
|
||||
}
|
||||
|
||||
/** Returns the desired interval between successive BSA downloads. */
|
||||
@Provides
|
||||
@Config("bsaDownloadInterval")
|
||||
public static Duration provideBsaDownloadInterval(RegistryConfigSettings config) {
|
||||
return Duration.standardMinutes(config.bsa.bsaDownloadIntervalMinutes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum period when a BSA download can be skipped due to the checksum-based
|
||||
* equality check with the previous download.
|
||||
*/
|
||||
@Provides
|
||||
@Config("bsaMaxNopInterval")
|
||||
public static Duration provideBsaMaxNopInterval(RegistryConfigSettings config) {
|
||||
return Duration.standardHours(config.bsa.bsaMaxNopIntervalHours);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Config("bsaLabelTxnBatchSize")
|
||||
public static int provideBsaLabelTxnBatchSize(RegistryConfigSettings config) {
|
||||
return config.bsa.bsaLabelTxnBatchSize;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Config("bsaAuthUrl")
|
||||
public static String provideBsaAuthUrl(RegistryConfigSettings config) {
|
||||
@@ -1415,6 +1456,27 @@ public final class RegistryConfig {
|
||||
return ImmutableMap.copyOf(config.bsa.dataUrls);
|
||||
}
|
||||
|
||||
/** Provides the BSA Http endpoint for reporting order processing status. */
|
||||
@Provides
|
||||
@Config("bsaOrderStatusUrl")
|
||||
public static String provideBsaOrderStatusUrls(RegistryConfigSettings config) {
|
||||
return config.bsa.orderStatusUrl;
|
||||
}
|
||||
|
||||
/** Provides the BSA Http endpoint for reporting new unblockable domains. */
|
||||
@Provides
|
||||
@Config("bsaAddUnblockableDomainsUrl")
|
||||
public static String provideBsaAddUnblockableDomainsUrls(RegistryConfigSettings config) {
|
||||
return String.format("%s?%s", config.bsa.unblockableDomainsUrl, "action=add");
|
||||
}
|
||||
|
||||
/** Provides the BSA Http endpoint for reporting domains that have become blockable. */
|
||||
@Provides
|
||||
@Config("bsaRemoveUnblockableDomainsUrl")
|
||||
public static String provideBsaRemoveUnblockableDomainsUrls(RegistryConfigSettings config) {
|
||||
return String.format("%s?%s", config.bsa.unblockableDomainsUrl, "action=remove");
|
||||
}
|
||||
|
||||
private static String formatComments(String text) {
|
||||
return Splitter.on('\n').omitEmptyStrings().trimResults().splitToList(text).stream()
|
||||
.map(s -> "# " + s)
|
||||
|
||||
@@ -267,8 +267,15 @@ public class RegistryConfigSettings {
|
||||
|
||||
/** Configurations for integration with Brand Safety Alliance (BSA) API. */
|
||||
public static class Bsa {
|
||||
public String bsaChecksumAlgorithm;
|
||||
public int bsaLockLeaseExpiryMinutes;
|
||||
public int bsaDownloadIntervalMinutes;
|
||||
public int bsaMaxNopIntervalHours;
|
||||
public int bsaLabelTxnBatchSize;
|
||||
public String authUrl;
|
||||
public int authTokenExpirySeconds;
|
||||
public Map<String, String> dataUrls;
|
||||
public String orderStatusUrl;
|
||||
public String unblockableDomainsUrl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -617,3 +617,7 @@ bsa:
|
||||
dataUrls:
|
||||
"BLOCK": "https://"
|
||||
"BLOCK_PLUS": "https://"
|
||||
# Http endpoint for reporting order processing status
|
||||
orderStatusUrl: "https://"
|
||||
# Http endpoint for reporting changes in the set of unblockable domains.
|
||||
unblockableDomainsUrl: "https://"
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
<!-- Test action -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>backend-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/bsa</url-pattern>
|
||||
<servlet-name>bsa-servlet</servlet-name>
|
||||
<url-pattern>/_dr/task/bsaDownload</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- Security config -->
|
||||
|
||||
@@ -19,6 +19,12 @@
|
||||
value="production"/>
|
||||
</system-properties>
|
||||
|
||||
<!-- Enable external traffic to go through VPC, required for static ip -->
|
||||
<vpc-access-connector>
|
||||
<name>projects/domain-registry/locations/us-central1/connectors/appengine-connector</name>
|
||||
<egress-setting>all-traffic</egress-setting>
|
||||
</vpc-access-connector>
|
||||
|
||||
<static-files>
|
||||
<include path="/*.html" expiration="1d"/>
|
||||
</static-files>
|
||||
|
||||
@@ -75,14 +75,6 @@ public class EppRequestHandler {
|
||||
&& eppOutput.getResponse().getResult().getCode() == SUCCESS_AND_CLOSE) {
|
||||
response.setHeader(ProxyHttpHeaders.EPP_SESSION, "close");
|
||||
}
|
||||
// If a login request returns a success, a logged-in header is added to the response to inform
|
||||
// the proxy that it is no longer necessary to send the full client certificate to the backend
|
||||
// for this connection.
|
||||
if (eppOutput.isResponse()
|
||||
&& eppOutput.getResponse().isLoginResponse()
|
||||
&& eppOutput.isSuccess()) {
|
||||
response.setHeader(ProxyHttpHeaders.LOGGED_IN, "true");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.atWarning().withCause(e).log("handleEppCommand general exception.");
|
||||
response.setStatus(SC_BAD_REQUEST);
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.google.common.net.InetAddresses;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import google.registry.config.RegistryConfig.Config;
|
||||
import google.registry.config.RegistryEnvironment;
|
||||
import google.registry.flows.EppException.AuthenticationErrorException;
|
||||
import google.registry.flows.certs.CertificateChecker;
|
||||
import google.registry.flows.certs.CertificateChecker.InsecureCertificateException;
|
||||
@@ -66,11 +67,11 @@ public class TlsCredentials implements TransportCredentials {
|
||||
public TlsCredentials(
|
||||
@Config("requireSslCertificates") boolean requireSslCertificates,
|
||||
@Header(ProxyHttpHeaders.CERTIFICATE_HASH) Optional<String> clientCertificateHash,
|
||||
@Header(ProxyHttpHeaders.IP_ADDRESS) Optional<String> clientAddress,
|
||||
Optional<InetAddress> clientInetAddr,
|
||||
CertificateChecker certificateChecker) {
|
||||
this.requireSslCertificates = requireSslCertificates;
|
||||
this.clientCertificateHash = clientCertificateHash;
|
||||
this.clientInetAddr = clientAddress.map(TlsCredentials::parseInetAddress);
|
||||
this.clientInetAddr = clientInetAddr;
|
||||
this.certificateChecker = certificateChecker;
|
||||
}
|
||||
|
||||
@@ -104,18 +105,25 @@ public class TlsCredentials implements TransportCredentials {
|
||||
}
|
||||
// In the rare unexpected case that the client inet address wasn't passed along at all, then
|
||||
// by default deny access.
|
||||
if (clientInetAddr.isPresent()) {
|
||||
for (CidrAddressBlock cidrAddressBlock : ipAddressAllowList) {
|
||||
if (cidrAddressBlock.contains(clientInetAddr.get())) {
|
||||
// IP address is in allow list; return early.
|
||||
return;
|
||||
}
|
||||
if (!clientInetAddr.isPresent()) {
|
||||
logger.atWarning().log(
|
||||
"Authentication error: Missing IP address for registrar %s.", registrar.getRegistrarId());
|
||||
throw new BadRegistrarIpAddressException(clientInetAddr);
|
||||
}
|
||||
for (CidrAddressBlock cidrAddressBlock : ipAddressAllowList) {
|
||||
if (cidrAddressBlock.contains(clientInetAddr.get())) {
|
||||
// IP address is in allow list; return early.
|
||||
return;
|
||||
}
|
||||
}
|
||||
logger.atInfo().log(
|
||||
logger.atWarning().log(
|
||||
"Authentication error: IP address %s is not allow-listed for registrar %s; allow list is:"
|
||||
+ " %s",
|
||||
clientInetAddr, registrar.getRegistrarId(), ipAddressAllowList);
|
||||
clientInetAddr,
|
||||
registrar.getRegistrarId(),
|
||||
RegistryEnvironment.get() == RegistryEnvironment.PRODUCTION
|
||||
? "redacted in production"
|
||||
: ipAddressAllowList);
|
||||
throw new BadRegistrarIpAddressException(clientInetAddr);
|
||||
}
|
||||
|
||||
@@ -232,7 +240,7 @@ public class TlsCredentials implements TransportCredentials {
|
||||
? String.format(
|
||||
"Registrar IP address %s is not in stored allow list",
|
||||
clientInetAddr.get().getHostAddress())
|
||||
: "Registrar IP address is not in stored allow list");
|
||||
: "Registrar IP address is missing");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,9 +257,14 @@ public class TlsCredentials implements TransportCredentials {
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Header(ProxyHttpHeaders.IP_ADDRESS)
|
||||
static Optional<String> provideIpAddress(HttpServletRequest req) {
|
||||
return extractOptionalHeader(req, ProxyHttpHeaders.IP_ADDRESS);
|
||||
static Optional<InetAddress> provideIpAddress(HttpServletRequest req) {
|
||||
Optional<String> clientAddress = extractOptionalHeader(req, ProxyHttpHeaders.IP_ADDRESS);
|
||||
Optional<String> fallbackClientAddress =
|
||||
extractOptionalHeader(req, ProxyHttpHeaders.IP_ADDRESS);
|
||||
Optional<InetAddress> clientInetAddr = clientAddress.map(TlsCredentials::parseInetAddress);
|
||||
return clientInetAddr.isPresent()
|
||||
? clientInetAddr
|
||||
: fallbackClientAddress.map(TlsCredentials::parseInetAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static google.registry.flows.domain.DomainFlowUtils.zeroInCurrency;
|
||||
import static google.registry.flows.domain.token.AllocationTokenFlowUtils.validateTokenForPossiblePremiumName;
|
||||
import static google.registry.pricing.PricingEngineProxy.getPricesForDomainName;
|
||||
import static google.registry.util.DomainNameUtils.getTldFromDomainName;
|
||||
import static google.registry.util.PreconditionsUtils.checkArgumentPresent;
|
||||
|
||||
import com.google.common.net.InternetDomainName;
|
||||
@@ -31,11 +30,13 @@ import google.registry.flows.custom.DomainPricingCustomLogic.RenewPriceParameter
|
||||
import google.registry.flows.custom.DomainPricingCustomLogic.RestorePriceParameters;
|
||||
import google.registry.flows.custom.DomainPricingCustomLogic.TransferPriceParameters;
|
||||
import google.registry.flows.custom.DomainPricingCustomLogic.UpdatePriceParameters;
|
||||
import google.registry.model.billing.BillingBase.RenewalPriceBehavior;
|
||||
import google.registry.model.billing.BillingRecurrence;
|
||||
import google.registry.model.domain.fee.BaseFee;
|
||||
import google.registry.model.domain.fee.BaseFee.FeeType;
|
||||
import google.registry.model.domain.fee.Fee;
|
||||
import google.registry.model.domain.token.AllocationToken;
|
||||
import google.registry.model.domain.token.AllocationToken.RegistrationBehavior;
|
||||
import google.registry.model.domain.token.AllocationToken.TokenBehavior;
|
||||
import google.registry.model.pricing.PremiumPricingEngine.DomainPrices;
|
||||
import google.registry.model.tld.Tld;
|
||||
@@ -132,12 +133,14 @@ public final class DomainPricingLogic {
|
||||
// recurrence is null if the domain is still available. Billing events are created
|
||||
// in the process of domain creation.
|
||||
if (billingRecurrence == null) {
|
||||
renewCost = getDomainRenewCostWithDiscount(domainPrices, years, allocationToken);
|
||||
renewCost =
|
||||
getDomainRenewCostWithDiscount(tld, domainPrices, dateTime, years, allocationToken);
|
||||
isRenewCostPremiumPrice = domainPrices.isPremium();
|
||||
} else {
|
||||
switch (billingRecurrence.getRenewalPriceBehavior()) {
|
||||
case DEFAULT:
|
||||
renewCost = getDomainRenewCostWithDiscount(domainPrices, years, allocationToken);
|
||||
renewCost =
|
||||
getDomainRenewCostWithDiscount(tld, domainPrices, dateTime, years, allocationToken);
|
||||
isRenewCostPremiumPrice = domainPrices.isPremium();
|
||||
break;
|
||||
// if the renewal price behavior is specified, then the renewal price should be the same
|
||||
@@ -156,10 +159,7 @@ public final class DomainPricingLogic {
|
||||
case NONPREMIUM:
|
||||
renewCost =
|
||||
getDomainCostWithDiscount(
|
||||
false,
|
||||
years,
|
||||
allocationToken,
|
||||
Tld.get(getTldFromDomainName(domainName)).getStandardRenewCost(dateTime));
|
||||
false, years, allocationToken, tld.getStandardRenewCost(dateTime));
|
||||
isRenewCostPremiumPrice = false;
|
||||
break;
|
||||
default:
|
||||
@@ -257,8 +257,20 @@ public final class DomainPricingLogic {
|
||||
|
||||
/** Returns the domain renew cost with allocation-token-related discounts applied. */
|
||||
private Money getDomainRenewCostWithDiscount(
|
||||
DomainPrices domainPrices, int years, Optional<AllocationToken> allocationToken)
|
||||
Tld tld,
|
||||
DomainPrices domainPrices,
|
||||
DateTime dateTime,
|
||||
int years,
|
||||
Optional<AllocationToken> allocationToken)
|
||||
throws AllocationTokenInvalidForPremiumNameException {
|
||||
// Short-circuit if the user sent an anchor-tenant or otherwise NONPREMIUM-renewal token
|
||||
if (allocationToken.isPresent()) {
|
||||
AllocationToken token = allocationToken.get();
|
||||
if (token.getRegistrationBehavior().equals(RegistrationBehavior.ANCHOR_TENANT)
|
||||
|| token.getRenewalPriceBehavior().equals(RenewalPriceBehavior.NONPREMIUM)) {
|
||||
return tld.getStandardRenewCost(dateTime).multipliedBy(years);
|
||||
}
|
||||
}
|
||||
return getDomainCostWithDiscount(
|
||||
domainPrices.isPremium(), years, allocationToken, domainPrices.getRenewCost());
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import static com.google.common.collect.Sets.difference;
|
||||
import static com.google.common.collect.Sets.union;
|
||||
import static google.registry.config.RegistryConfig.getEppResourceCachingDuration;
|
||||
import static google.registry.config.RegistryConfig.getEppResourceMaxCachedEntries;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.replicaTm;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.CollectionUtils.nullToEmpty;
|
||||
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
|
||||
@@ -357,13 +358,13 @@ public abstract class EppResource extends UpdateAutoTimestampEntity implements B
|
||||
|
||||
@Override
|
||||
public EppResource load(VKey<? extends EppResource> key) {
|
||||
return tm().reTransact(() -> tm().loadByKey(key));
|
||||
return replicaTm().reTransact(() -> replicaTm().loadByKey(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<VKey<? extends EppResource>, EppResource> loadAll(
|
||||
Iterable<? extends VKey<? extends EppResource>> keys) {
|
||||
return tm().reTransact(() -> tm().loadByKeys(keys));
|
||||
return replicaTm().reTransact(() -> replicaTm().loadByKeys(keys));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -165,10 +165,11 @@ public final class ForeignKeyUtils {
|
||||
* foreign keys should not use this cache.
|
||||
*
|
||||
* <p>Note that here the key of the {@link LoadingCache} is of type {@code VKey<? extends
|
||||
* EppResource>}, but they are not legal {VKey}s to {@link EppResource}s, whose keys are the SQL
|
||||
* primary keys, i.e. the {@code repoId}s. Instead, their keys are the foreign keys used to query
|
||||
* the database. We use {@link VKey} here because it is a convenient composite class that contains
|
||||
* both the resource type and the foreign key, which are needed to for the query and caching.
|
||||
* EppResource>}, but they are not legal {@link VKey}s to {@link EppResource}s, whose keys are the
|
||||
* SQL primary keys, i.e. the {@code repoId}s. Instead, their keys are the foreign keys used to
|
||||
* query the database. We use {@link VKey} here because it is a convenient composite class that
|
||||
* contains both the resource type and the foreign key, which are needed to for the query and
|
||||
* caching.
|
||||
*
|
||||
* <p>Also note that the value type of this cache is {@link Optional} because the foreign keys in
|
||||
* question are coming from external commands, and thus don't necessarily represent entities in
|
||||
|
||||
@@ -256,6 +256,11 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
|
||||
return VKey.create(Tld.class, tldStr);
|
||||
}
|
||||
|
||||
/** Checks if {@code tld} is enrolled with BSA. */
|
||||
public static boolean isEnrolledWithBsa(Tld tld, DateTime now) {
|
||||
return tld.getBsaEnrollStartTime().orElse(END_OF_TIME).isBefore(now);
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the pricing engine that this TLD uses.
|
||||
*
|
||||
@@ -550,9 +555,15 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
|
||||
@JsonSerialize(using = SortedEnumSetSerializer.class)
|
||||
Set<IdnTableEnum> idnTables;
|
||||
|
||||
// TODO(11/30/2023): uncomment below two lines
|
||||
// /** The start time of this TLD's enrollment in the BSA program, if applicable. */
|
||||
// @JsonIgnore @Nullable DateTime bsaEnrollStartTime;
|
||||
/**
|
||||
* The start time of this TLD's enrollment in the BSA program, if applicable.
|
||||
*
|
||||
* <p>This property is excluded from source-based configuration and is managed directly in the
|
||||
* database.
|
||||
*/
|
||||
// TODO(b/309175410): implement setup and cleanup procedure for joining or leaving BSA, and see
|
||||
// if it can be integrated with the ConfigTldCommand.
|
||||
@JsonIgnore @Nullable DateTime bsaEnrollStartTime;
|
||||
|
||||
public String getTldStr() {
|
||||
return tldStr;
|
||||
@@ -574,12 +585,9 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
|
||||
}
|
||||
|
||||
/** Returns the time when this TLD was enrolled in the Brand Safety Alliance (BSA) program. */
|
||||
@JsonIgnore // Annotation can be removed once we add the field and annotate it.
|
||||
@Nullable
|
||||
public DateTime getBsaEnrollStartTime() {
|
||||
// TODO(11/30/2023): uncomment below.
|
||||
// return this.bsaEnrollStartTime;
|
||||
return null;
|
||||
@JsonIgnore
|
||||
public Optional<DateTime> getBsaEnrollStartTime() {
|
||||
return Optional.ofNullable(this.bsaEnrollStartTime);
|
||||
}
|
||||
|
||||
/** Retrieve whether invoicing is enabled. */
|
||||
@@ -1101,10 +1109,9 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setBsaEnrollStartTime(DateTime enrollTime) {
|
||||
public Builder setBsaEnrollStartTime(Optional<DateTime> enrollTime) {
|
||||
// TODO(b/309175133): forbid if enrolled with BSA
|
||||
// TODO(11/30/2023): uncomment below line
|
||||
// getInstance().bsaEnrollStartTime = enrollTime;
|
||||
getInstance().bsaEnrollStartTime = enrollTime.orElse(null);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ import org.joda.money.Money;
|
||||
* {@link PremiumList} object in SQL, and caching these entries so that future lookups can be
|
||||
* quicker.
|
||||
*/
|
||||
public class PremiumListDao {
|
||||
public final class PremiumListDao {
|
||||
|
||||
/**
|
||||
* In-memory cache for premium lists.
|
||||
@@ -102,7 +102,7 @@ public class PremiumListDao {
|
||||
/**
|
||||
* Returns the most recent revision of the PremiumList with the specified name, if it exists.
|
||||
*
|
||||
* <p>Note that this does not load <code>PremiumList.labelsToPrices</code>! If you need to check
|
||||
* <p>Note that this does not load {@code PremiumList.labelsToPrices}! If you need to check
|
||||
* prices, use {@link #getPremiumPrice}.
|
||||
*/
|
||||
public static Optional<PremiumList> getLatestRevision(String premiumListName) {
|
||||
@@ -169,7 +169,7 @@ public class PremiumListDao {
|
||||
}
|
||||
|
||||
private static Optional<PremiumList> getLatestRevisionUncached(String premiumListName) {
|
||||
return tm().transact(
|
||||
return tm().reTransact(
|
||||
() ->
|
||||
tm().query(
|
||||
"FROM PremiumList WHERE name = :name ORDER BY revisionId DESC",
|
||||
@@ -197,10 +197,10 @@ public class PremiumListDao {
|
||||
|
||||
/**
|
||||
* Loads the price for the given revisionId + label combination. Note that this does a database
|
||||
* retrieval so it should only be done in a cached context.
|
||||
* retrieval, so it should only be done in a cached context.
|
||||
*/
|
||||
static Optional<BigDecimal> getPriceForLabelUncached(RevisionIdAndLabel revisionIdAndLabel) {
|
||||
return tm().transact(
|
||||
return tm().reTransact(
|
||||
() ->
|
||||
tm().query(
|
||||
"SELECT pe.price FROM PremiumEntry pe WHERE pe.revisionId = :revisionId"
|
||||
|
||||
@@ -199,7 +199,7 @@ public final class ReservedList
|
||||
public synchronized ImmutableMap<String, ReservedListEntry> getReservedListEntries() {
|
||||
if (reservedListMap == null) {
|
||||
reservedListMap =
|
||||
tm().transact(
|
||||
tm().reTransact(
|
||||
() ->
|
||||
tm()
|
||||
.createQueryComposer(ReservedListEntry.class)
|
||||
|
||||
@@ -47,7 +47,7 @@ public class ReservedListDao {
|
||||
* exists.
|
||||
*/
|
||||
public static Optional<ReservedList> getLatestRevision(String reservedListName) {
|
||||
return tm().transact(
|
||||
return tm().reTransact(
|
||||
() ->
|
||||
tm().query(
|
||||
"FROM ReservedList WHERE revisionId IN "
|
||||
|
||||
@@ -65,7 +65,7 @@ public class ClaimsListDao {
|
||||
* doesn't exist.
|
||||
*/
|
||||
private static ClaimsList getUncached() {
|
||||
return tm().transact(
|
||||
return tm().reTransact(
|
||||
() -> {
|
||||
Long revisionId =
|
||||
tm().query("SELECT MAX(revisionId) FROM ClaimsList", Long.class)
|
||||
|
||||
@@ -267,7 +267,7 @@ public abstract class PersistenceModule {
|
||||
name -> overrides.put(HIKARI_DS_CLOUD_SQL_INSTANCE, name));
|
||||
overrides.put(
|
||||
Environment.ISOLATION, TransactionIsolationLevel.TRANSACTION_REPEATABLE_READ.name());
|
||||
return new JpaTransactionManagerImpl(create(overrides), clock);
|
||||
return new JpaTransactionManagerImpl(create(overrides), clock, true);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@@ -283,7 +283,7 @@ public abstract class PersistenceModule {
|
||||
name -> overrides.put(HIKARI_DS_CLOUD_SQL_INSTANCE, name));
|
||||
overrides.put(
|
||||
Environment.ISOLATION, TransactionIsolationLevel.TRANSACTION_REPEATABLE_READ.name());
|
||||
return new JpaTransactionManagerImpl(create(overrides), clock);
|
||||
return new JpaTransactionManagerImpl(create(overrides), clock, true);
|
||||
}
|
||||
|
||||
/** Constructs the {@link EntityManagerFactory} instance. */
|
||||
|
||||
@@ -33,6 +33,7 @@ import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Streams;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.google.common.flogger.StackSize;
|
||||
import google.registry.config.RegistryEnvironment;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.persistence.JpaRetries;
|
||||
import google.registry.persistence.PersistenceModule.TransactionIsolationLevel;
|
||||
@@ -85,13 +86,19 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
|
||||
// EntityManagerFactory is thread safe.
|
||||
private final EntityManagerFactory emf;
|
||||
private final Clock clock;
|
||||
private final boolean readOnly;
|
||||
|
||||
private static final ThreadLocal<TransactionInfo> transactionInfo =
|
||||
ThreadLocal.withInitial(TransactionInfo::new);
|
||||
|
||||
public JpaTransactionManagerImpl(EntityManagerFactory emf, Clock clock) {
|
||||
public JpaTransactionManagerImpl(EntityManagerFactory emf, Clock clock, boolean readOnly) {
|
||||
this.emf = emf;
|
||||
this.clock = clock;
|
||||
this.readOnly = readOnly;
|
||||
}
|
||||
|
||||
public JpaTransactionManagerImpl(EntityManagerFactory emf, Clock clock) {
|
||||
this(emf, clock, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -158,7 +165,10 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
|
||||
if (!getHibernateAllowNestedTransactions()) {
|
||||
throw new IllegalStateException(NESTED_TRANSACTION_MESSAGE);
|
||||
}
|
||||
logger.atWarning().withStackTrace(StackSize.MEDIUM).log(NESTED_TRANSACTION_MESSAGE);
|
||||
if (RegistryEnvironment.get() != RegistryEnvironment.PRODUCTION
|
||||
&& RegistryEnvironment.get() != RegistryEnvironment.UNITTEST) {
|
||||
logger.atWarning().withStackTrace(StackSize.MEDIUM).log(NESTED_TRANSACTION_MESSAGE);
|
||||
}
|
||||
// This prevents inner transaction from retrying, thus avoiding a cascade retry effect.
|
||||
return transactNoRetry(work, isolationLevel);
|
||||
}
|
||||
@@ -200,6 +210,10 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
|
||||
try {
|
||||
txn.begin();
|
||||
txnInfo.start(clock);
|
||||
if (readOnly) {
|
||||
getEntityManager().createNativeQuery("SET TRANSACTION READ ONLY").executeUpdate();
|
||||
logger.atInfo().log("Using read-only SQL replica");
|
||||
}
|
||||
if (isolationLevel != null && isolationLevel != getDefaultTransactionIsolationLevel()) {
|
||||
getEntityManager()
|
||||
.createNativeQuery(
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.google.common.net.MediaType;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URLConnection;
|
||||
import java.util.Random;
|
||||
|
||||
@@ -36,26 +37,37 @@ public final class UrlConnectionUtils {
|
||||
|
||||
private UrlConnectionUtils() {}
|
||||
|
||||
/** Retrieves the response from the given connection as a byte array. */
|
||||
public static byte[] getResponseBytes(URLConnection connection) throws IOException {
|
||||
try (InputStream is = connection.getInputStream()) {
|
||||
/**
|
||||
* Retrieves the response from the given connection as a byte array.
|
||||
*
|
||||
* <p>Note that in the event the response code is 4XX or 5XX, we use the error stream as any
|
||||
* payload is included there.
|
||||
*
|
||||
* @see HttpURLConnection#getErrorStream()
|
||||
*/
|
||||
public static byte[] getResponseBytes(HttpURLConnection connection) throws IOException {
|
||||
int responseCode = connection.getResponseCode();
|
||||
try (InputStream is =
|
||||
responseCode < 400 ? connection.getInputStream() : connection.getErrorStream()) {
|
||||
return ByteStreams.toByteArray(is);
|
||||
} catch (NullPointerException e) {
|
||||
return new byte[] {};
|
||||
}
|
||||
}
|
||||
|
||||
/** Sets auth on the given connection with the given username/password. */
|
||||
public static void setBasicAuth(URLConnection connection, String username, String password) {
|
||||
public static void setBasicAuth(HttpURLConnection connection, String username, String password) {
|
||||
setBasicAuth(connection, String.format("%s:%s", username, password));
|
||||
}
|
||||
|
||||
/** Sets auth on the given connection with the given string, formatted "username:password". */
|
||||
public static void setBasicAuth(URLConnection connection, String usernameAndPassword) {
|
||||
public static void setBasicAuth(HttpURLConnection connection, String usernameAndPassword) {
|
||||
String token = base64().encode(usernameAndPassword.getBytes(UTF_8));
|
||||
connection.setRequestProperty(AUTHORIZATION, "Basic " + token);
|
||||
}
|
||||
|
||||
/** Sets the given byte[] payload on the given connection with a particular content type. */
|
||||
public static void setPayload(URLConnection connection, byte[] bytes, String contentType)
|
||||
public static void setPayload(HttpURLConnection connection, byte[] bytes, String contentType)
|
||||
throws IOException {
|
||||
connection.setRequestProperty(CONTENT_TYPE, contentType);
|
||||
connection.setDoOutput(true);
|
||||
@@ -72,7 +84,7 @@ public final class UrlConnectionUtils {
|
||||
* @see <a href="http://www.ietf.org/rfc/rfc2388.txt">RFC2388 - Returning Values from Forms</a>
|
||||
*/
|
||||
public static void setPayloadMultipart(
|
||||
URLConnection connection,
|
||||
HttpURLConnection connection,
|
||||
String name,
|
||||
String filename,
|
||||
MediaType contentType,
|
||||
|
||||
@@ -122,6 +122,13 @@ public class ConfigureTldCommand extends MutatingCommand {
|
||||
checkPremiumList(newTld);
|
||||
checkDnsWriters(newTld);
|
||||
checkCurrency(newTld);
|
||||
// bsaEnrollStartTime only exists in DB. Need to carry it over to the updated copy. See Tld.java
|
||||
// for more information.
|
||||
Optional<DateTime> bsaEnrollTime =
|
||||
Optional.ofNullable(oldTld).flatMap(Tld::getBsaEnrollStartTime);
|
||||
if (bsaEnrollTime.isPresent()) {
|
||||
newTld = newTld.asBuilder().setBsaEnrollStartTime(bsaEnrollTime).build();
|
||||
}
|
||||
// Set the new TLD to breakglass mode if breakglass flag was used
|
||||
if (breakglass) {
|
||||
newTld = newTld.asBuilder().setBreakglassMode(true).build();
|
||||
|
||||
@@ -463,8 +463,7 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand {
|
||||
}
|
||||
}
|
||||
|
||||
private void checkReservedListValidityForTld(String tld, Set<String> reservedListNames)
|
||||
throws UnsupportedEncodingException {
|
||||
private void checkReservedListValidityForTld(String tld, Set<String> reservedListNames) {
|
||||
ImmutableList.Builder<String> builder = new ImmutableList.Builder<>();
|
||||
for (String reservedListName : reservedListNames) {
|
||||
if (!reservedListName.startsWith("common_") && !reservedListName.startsWith(tld + "_")) {
|
||||
|
||||
@@ -67,9 +67,12 @@ abstract class UpdateOrDeleteAllocationTokensCommand extends ConfirmingCommand {
|
||||
checkArgument(!prefix.isEmpty(), "Provided prefix should not be blank");
|
||||
return tm().transact(
|
||||
() ->
|
||||
tm().loadAllOf(AllocationToken.class).stream()
|
||||
.filter(token -> token.getToken().startsWith(prefix))
|
||||
.map(AllocationToken::createVKey)
|
||||
tm().query(
|
||||
"SELECT token FROM AllocationToken WHERE token LIKE :prefix",
|
||||
String.class)
|
||||
.setParameter("prefix", String.format("%s%%", prefix))
|
||||
.getResultStream()
|
||||
.map(token -> VKey.create(AllocationToken.class, token))
|
||||
.collect(toImmutableList()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
package google.registry.tools;
|
||||
|
||||
import static google.registry.util.DiffUtils.prettyPrintEntityDeepDiff;
|
||||
import static google.registry.util.ListNamingUtils.convertFilePathToName;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
@@ -46,17 +47,27 @@ final class UpdateReservedListCommand extends CreateOrUpdateReservedListCommand
|
||||
.setReservedListMapFromLines(allLines)
|
||||
.setShouldPublish(shouldPublish);
|
||||
reservedList = updated.build();
|
||||
// only call stageEntityChange if there are changes in entries
|
||||
|
||||
if (!existingReservedList
|
||||
.getReservedListEntries()
|
||||
.equals(reservedList.getReservedListEntries())) {
|
||||
return String.format(
|
||||
"Update reserved list for %s?\nOld list: %s\n New list: %s",
|
||||
name,
|
||||
outputReservedListEntries(existingReservedList),
|
||||
outputReservedListEntries(reservedList));
|
||||
boolean shouldPublishChanged =
|
||||
existingReservedList.getShouldPublish() != reservedList.getShouldPublish();
|
||||
boolean reservedListEntriesChanged =
|
||||
!existingReservedList
|
||||
.getReservedListEntries()
|
||||
.equals(reservedList.getReservedListEntries());
|
||||
if (!shouldPublishChanged && !reservedListEntriesChanged) {
|
||||
return "No entity changes to apply.";
|
||||
}
|
||||
return "No entity changes to apply.";
|
||||
String result = String.format("Update reserved list for %s?\n", name);
|
||||
if (shouldPublishChanged) {
|
||||
result +=
|
||||
String.format(
|
||||
"shouldPublish: %s -> %s\n",
|
||||
existingReservedList.getShouldPublish(), reservedList.getShouldPublish());
|
||||
}
|
||||
if (reservedListEntriesChanged) {
|
||||
result +=
|
||||
prettyPrintEntityDeepDiff(
|
||||
existingReservedList.getReservedListEntries(), reservedList.getReservedListEntries());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import static google.registry.util.X509Utils.loadCertificate;
|
||||
|
||||
import com.beust.jcommander.Parameter;
|
||||
import com.beust.jcommander.Parameters;
|
||||
import com.google.common.net.InetAddresses;
|
||||
import google.registry.flows.TlsCredentials;
|
||||
import google.registry.flows.certs.CertificateChecker;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
@@ -85,7 +86,7 @@ final class ValidateLoginCredentialsCommand implements Command {
|
||||
new TlsCredentials(
|
||||
true,
|
||||
Optional.ofNullable(clientCertificateHash),
|
||||
Optional.ofNullable(clientIpAddress),
|
||||
Optional.ofNullable(InetAddresses.forString(clientIpAddress)),
|
||||
certificateChecker)
|
||||
.validate(registrar, password);
|
||||
checkState(
|
||||
|
||||
@@ -19,6 +19,7 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Ascii;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import google.registry.model.CreateAutoTimestamp;
|
||||
@@ -33,6 +34,7 @@ import google.registry.ui.server.registrar.JsonGetAction;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.TypedQuery;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/** Returns a (paginated) list of domains for a particular registrar. */
|
||||
@@ -49,6 +51,8 @@ public class ConsoleDomainListAction implements JsonGetAction {
|
||||
private static final String DOMAIN_QUERY_TEMPLATE =
|
||||
"FROM Domain WHERE currentSponsorRegistrarId = :registrarId AND deletionTime >"
|
||||
+ " :deletedAfterTime AND creationTime <= :createdBeforeTime";
|
||||
private static final String SEARCH_TERM_QUERY = " AND LOWER(domainName) LIKE :searchTerm";
|
||||
private static final String ORDER_BY_STATEMENT = " ORDER BY creationTime DESC";
|
||||
|
||||
private final AuthResult authResult;
|
||||
private final Response response;
|
||||
@@ -58,6 +62,7 @@ public class ConsoleDomainListAction implements JsonGetAction {
|
||||
private final int pageNumber;
|
||||
private final int resultsPerPage;
|
||||
private final Optional<Long> totalResults;
|
||||
private final Optional<String> searchTerm;
|
||||
|
||||
@Inject
|
||||
public ConsoleDomainListAction(
|
||||
@@ -68,7 +73,8 @@ public class ConsoleDomainListAction implements JsonGetAction {
|
||||
@Parameter("checkpointTime") Optional<DateTime> checkpointTime,
|
||||
@Parameter("pageNumber") Optional<Integer> pageNumber,
|
||||
@Parameter("resultsPerPage") Optional<Integer> resultsPerPage,
|
||||
@Parameter("totalResults") Optional<Long> totalResults) {
|
||||
@Parameter("totalResults") Optional<Long> totalResults,
|
||||
@Parameter("searchTerm") Optional<String> searchTerm) {
|
||||
this.authResult = authResult;
|
||||
this.response = response;
|
||||
this.gson = gson;
|
||||
@@ -77,6 +83,7 @@ public class ConsoleDomainListAction implements JsonGetAction {
|
||||
this.pageNumber = pageNumber.orElse(0);
|
||||
this.resultsPerPage = resultsPerPage.orElse(DEFAULT_RESULTS_PER_PAGE);
|
||||
this.totalResults = totalResults;
|
||||
this.searchTerm = searchTerm;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -110,13 +117,13 @@ public class ConsoleDomainListAction implements JsonGetAction {
|
||||
long actualTotalResults =
|
||||
totalResults.orElseGet(
|
||||
() ->
|
||||
tm().query("SELECT COUNT(*) " + DOMAIN_QUERY_TEMPLATE, Long.class)
|
||||
createCountQuery()
|
||||
.setParameter("registrarId", registrarId)
|
||||
.setParameter("createdBeforeTime", checkpointTimestamp)
|
||||
.setParameter("deletedAfterTime", checkpoint)
|
||||
.getSingleResult());
|
||||
List<Domain> domains =
|
||||
tm().query(DOMAIN_QUERY_TEMPLATE + " ORDER BY creationTime DESC", Domain.class)
|
||||
createDomainQuery()
|
||||
.setParameter("registrarId", registrarId)
|
||||
.setParameter("createdBeforeTime", checkpointTimestamp)
|
||||
.setParameter("deletedAfterTime", checkpoint)
|
||||
@@ -127,6 +134,26 @@ public class ConsoleDomainListAction implements JsonGetAction {
|
||||
response.setStatus(HttpStatusCodes.STATUS_CODE_OK);
|
||||
}
|
||||
|
||||
/** Creates the query to get the total number of matching domains, interpolating as necessary. */
|
||||
private TypedQuery<Long> createCountQuery() {
|
||||
String queryString = "SELECT COUNT(*) " + DOMAIN_QUERY_TEMPLATE;
|
||||
if (searchTerm.isPresent() && !searchTerm.get().isEmpty()) {
|
||||
return tm().query(queryString + SEARCH_TERM_QUERY, Long.class)
|
||||
.setParameter("searchTerm", String.format("%%%s%%", Ascii.toLowerCase(searchTerm.get())));
|
||||
}
|
||||
return tm().query(queryString, Long.class);
|
||||
}
|
||||
|
||||
/** Creates the query to retrieve the matching domains themselves, interpolating as necessary. */
|
||||
private TypedQuery<Domain> createDomainQuery() {
|
||||
if (searchTerm.isPresent() && !searchTerm.get().isEmpty()) {
|
||||
return tm().query(
|
||||
DOMAIN_QUERY_TEMPLATE + SEARCH_TERM_QUERY + ORDER_BY_STATEMENT, Domain.class)
|
||||
.setParameter("searchTerm", String.format("%%%s%%", Ascii.toLowerCase(searchTerm.get())));
|
||||
}
|
||||
return tm().query(DOMAIN_QUERY_TEMPLATE + ORDER_BY_STATEMENT, Domain.class);
|
||||
}
|
||||
|
||||
private void writeBadRequest(String message) {
|
||||
response.setPayload(message);
|
||||
response.setStatus(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
|
||||
@@ -226,4 +226,10 @@ public final class RegistrarConsoleModule {
|
||||
public static Optional<Long> provideTotalResults(HttpServletRequest req) {
|
||||
return extractOptionalParameter(req, "totalResults").map(Long::valueOf);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Parameter("searchTerm")
|
||||
public static Optional<String> provideSearchTerm(HttpServletRequest req) {
|
||||
return extractOptionalParameter(req, "searchTerm");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,38 +15,65 @@
|
||||
package google.registry.bsa;
|
||||
|
||||
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.tldconfig.idn.IdnTableEnum.EXTENDED_LATIN;
|
||||
import static google.registry.tldconfig.idn.IdnTableEnum.JA;
|
||||
import static google.registry.tldconfig.idn.IdnTableEnum.UNCONFUSABLE_LATIN;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import google.registry.model.tld.Tld;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationWithCoverageExtension;
|
||||
import google.registry.testing.FakeClock;
|
||||
import java.util.Optional;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
/** Unit tests for {@link IdnChecker}. */
|
||||
public class IdnCheckerTest {
|
||||
|
||||
@Mock Tld jaonly;
|
||||
@Mock Tld jandelatin;
|
||||
@Mock Tld strictlatin;
|
||||
FakeClock fakeClock = new FakeClock();
|
||||
|
||||
@RegisterExtension
|
||||
final JpaIntegrationWithCoverageExtension jpa =
|
||||
new JpaTestExtensions.Builder().withClock(fakeClock).buildIntegrationWithCoverageExtension();
|
||||
|
||||
Tld jaonly;
|
||||
Tld jandelatin;
|
||||
Tld strictlatin;
|
||||
IdnChecker idnChecker;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
idnChecker =
|
||||
new IdnChecker(
|
||||
ImmutableMap.of(
|
||||
JA,
|
||||
ImmutableSet.of(jandelatin, jaonly),
|
||||
EXTENDED_LATIN,
|
||||
ImmutableSet.of(jandelatin),
|
||||
UNCONFUSABLE_LATIN,
|
||||
ImmutableSet.of(strictlatin)));
|
||||
jaonly = createTld("jaonly");
|
||||
jandelatin = createTld("jandelatin");
|
||||
strictlatin = createTld("strictlatin");
|
||||
|
||||
jaonly =
|
||||
persistResource(
|
||||
jaonly
|
||||
.asBuilder()
|
||||
.setBsaEnrollStartTime(Optional.of(fakeClock.nowUtc()))
|
||||
.setIdnTables(ImmutableSet.of(JA))
|
||||
.build());
|
||||
jandelatin =
|
||||
persistResource(
|
||||
jandelatin
|
||||
.asBuilder()
|
||||
.setBsaEnrollStartTime(Optional.of(fakeClock.nowUtc()))
|
||||
.setIdnTables(ImmutableSet.of(JA, EXTENDED_LATIN))
|
||||
.build());
|
||||
strictlatin =
|
||||
persistResource(
|
||||
strictlatin
|
||||
.asBuilder()
|
||||
.setBsaEnrollStartTime(Optional.of(fakeClock.nowUtc()))
|
||||
.setIdnTables(ImmutableSet.of(UNCONFUSABLE_LATIN))
|
||||
.build());
|
||||
fakeClock.advanceOneMilli();
|
||||
idnChecker = new IdnChecker(fakeClock);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -23,6 +23,7 @@ import static google.registry.util.X509Utils.getCertificateHash;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedMap;
|
||||
import com.google.common.net.InetAddresses;
|
||||
import google.registry.flows.certs.CertificateChecker;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
|
||||
@@ -66,7 +67,7 @@ class EppLoginTlsTest extends EppTestCase {
|
||||
new TlsCredentials(
|
||||
true,
|
||||
Optional.ofNullable(clientCertificateHash),
|
||||
Optional.of("192.168.1.100:54321"),
|
||||
Optional.of(InetAddresses.forString("192.168.1.100")),
|
||||
certificateChecker));
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,6 @@ import google.registry.persistence.VKey;
|
||||
import google.registry.testing.FakeClock;
|
||||
import google.registry.testing.FakeHttpSession;
|
||||
import google.registry.testing.FakeResponse;
|
||||
import google.registry.util.ProxyHttpHeaders;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
@@ -126,10 +125,6 @@ public class EppTestCase {
|
||||
setUpSession();
|
||||
FakeResponse response = executeXmlCommand(input);
|
||||
|
||||
// Check that the logged-in header was added to the response
|
||||
assertThat(response.getHeaders())
|
||||
.isEqualTo(ImmutableMap.of(ProxyHttpHeaders.LOGGED_IN, "true"));
|
||||
|
||||
verifyAndReturnOutput(response.getPayload(), expectedOutput, inputFilename, outputFilename);
|
||||
}
|
||||
|
||||
@@ -146,10 +141,6 @@ public class EppTestCase {
|
||||
setUpSession();
|
||||
FakeResponse response = executeXmlCommand(input);
|
||||
|
||||
// Checks that the Logged-In header is not in the response. If testing the login command, use
|
||||
// assertLoginCommandAndResponse instead of this method.
|
||||
assertThat(response.getHeaders()).doesNotContainEntry(ProxyHttpHeaders.LOGGED_IN, "true");
|
||||
|
||||
return verifyAndReturnOutput(
|
||||
response.getPayload(), expectedOutput, inputFilename, outputFilename);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedMap;
|
||||
import com.google.common.net.InetAddresses;
|
||||
import com.google.common.testing.TestLogHandler;
|
||||
import google.registry.flows.certs.CertificateChecker;
|
||||
import google.registry.model.eppcommon.Trid;
|
||||
@@ -186,7 +187,10 @@ class FlowRunnerTest {
|
||||
void testRun_loggingStatement_tlsCredentials() throws Exception {
|
||||
flowRunner.credentials =
|
||||
new TlsCredentials(
|
||||
true, Optional.of("abc123def"), Optional.of("127.0.0.1"), certificateChecker);
|
||||
true,
|
||||
Optional.of("abc123def"),
|
||||
Optional.of(InetAddresses.forString("127.0.0.1")),
|
||||
certificateChecker);
|
||||
flowRunner.run(eppMetricBuilder);
|
||||
assertThat(Splitter.on("\n\t").split(findFirstLogMessageByPrefix(handler, "EPP Command\n\t")))
|
||||
.contains("TlsCredentials{clientCertificateHash=abc123def," + " clientAddress=/127.0.0.1}");
|
||||
|
||||
@@ -27,6 +27,7 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedMap;
|
||||
import com.google.common.net.InetAddresses;
|
||||
import google.registry.flows.TlsCredentials.BadRegistrarIpAddressException;
|
||||
import google.registry.flows.TlsCredentials.MissingRegistrarCertificateException;
|
||||
import google.registry.flows.TlsCredentials.RegistrarCertificateNotConfiguredException;
|
||||
@@ -71,7 +72,11 @@ final class TlsCredentialsTest {
|
||||
@Test
|
||||
void testClientCertificateAndHash_missing() {
|
||||
TlsCredentials tls =
|
||||
new TlsCredentials(true, Optional.empty(), Optional.of("192.168.1.1"), certificateChecker);
|
||||
new TlsCredentials(
|
||||
true,
|
||||
Optional.empty(),
|
||||
Optional.of(InetAddresses.forString("192.168.1.1")),
|
||||
certificateChecker);
|
||||
persistResource(
|
||||
loadRegistrar("TheRegistrar")
|
||||
.asBuilder()
|
||||
@@ -83,10 +88,13 @@ final class TlsCredentialsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void test_missingIpAddress_doesntAllowAccess() {
|
||||
void test_wrongIpAddress_doesntAllowAccess() {
|
||||
TlsCredentials tls =
|
||||
new TlsCredentials(
|
||||
false, Optional.of("certHash"), Optional.of("127.0.0.1"), certificateChecker);
|
||||
false,
|
||||
Optional.of("certHash"),
|
||||
Optional.of(InetAddresses.forString("127.0.0.1")),
|
||||
certificateChecker);
|
||||
persistResource(
|
||||
loadRegistrar("TheRegistrar")
|
||||
.asBuilder()
|
||||
@@ -104,11 +112,33 @@ final class TlsCredentialsTest {
|
||||
.isEqualTo("Registrar IP address 127.0.0.1 is not in stored allow list");
|
||||
}
|
||||
|
||||
@Test
|
||||
void test_missingIpAddress_doesntAllowAccess() {
|
||||
TlsCredentials tls =
|
||||
new TlsCredentials(false, Optional.of("certHash"), Optional.empty(), certificateChecker);
|
||||
persistResource(
|
||||
loadRegistrar("TheRegistrar")
|
||||
.asBuilder()
|
||||
.setClientCertificate(SAMPLE_CERT, clock.nowUtc())
|
||||
.setIpAddressAllowList(ImmutableSet.of(CidrAddressBlock.create("3.5.8.13")))
|
||||
.build());
|
||||
|
||||
BadRegistrarIpAddressException thrown =
|
||||
assertThrows(
|
||||
BadRegistrarIpAddressException.class,
|
||||
() -> tls.validate(Registrar.loadByRegistrarId("TheRegistrar").get(), "password"));
|
||||
|
||||
assertThat(thrown).hasMessageThat().isEqualTo("Registrar IP address is missing");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testClientCertificate_notConfigured() {
|
||||
TlsCredentials tls =
|
||||
new TlsCredentials(
|
||||
true, Optional.of("hash"), Optional.of("192.168.1.1"), certificateChecker);
|
||||
true,
|
||||
Optional.of("hash"),
|
||||
Optional.of(InetAddresses.forString("192.168.1.1")),
|
||||
certificateChecker);
|
||||
persistResource(loadRegistrar("TheRegistrar").asBuilder().build());
|
||||
assertThrows(
|
||||
RegistrarCertificateNotConfiguredException.class,
|
||||
@@ -119,7 +149,10 @@ final class TlsCredentialsTest {
|
||||
void test_validateCertificateHash_canBeConfiguredToBypassCerts() throws Exception {
|
||||
TlsCredentials tls =
|
||||
new TlsCredentials(
|
||||
false, Optional.of("certHash"), Optional.of("192.168.1.1"), certificateChecker);
|
||||
false,
|
||||
Optional.of("certHash"),
|
||||
Optional.of(InetAddresses.forString("192.168.1.1")),
|
||||
certificateChecker);
|
||||
persistResource(
|
||||
loadRegistrar("TheRegistrar")
|
||||
.asBuilder()
|
||||
@@ -134,7 +167,10 @@ final class TlsCredentialsTest {
|
||||
void test_validateCertificateHash_passWithFailOverCerticate() throws Exception {
|
||||
TlsCredentials tls =
|
||||
new TlsCredentials(
|
||||
false, Optional.of(SAMPLE_CERT_HASH), Optional.of("192.168.1.1"), certificateChecker);
|
||||
false,
|
||||
Optional.of(SAMPLE_CERT_HASH),
|
||||
Optional.of(InetAddresses.forString("192.168.1.1")),
|
||||
certificateChecker);
|
||||
persistResource(
|
||||
loadRegistrar("TheRegistrar")
|
||||
.asBuilder()
|
||||
|
||||
@@ -340,6 +340,7 @@ class DomainCheckFlowTest extends ResourceCheckFlowTestCase<DomainCheckFlow, Dom
|
||||
new AllocationToken.Builder()
|
||||
.setToken("abc123")
|
||||
.setTokenType(UNLIMITED_USE)
|
||||
.setAllowedEppActions(ImmutableSet.of(CommandName.CREATE))
|
||||
.setDiscountFraction(0.5)
|
||||
.setDiscountYears(2)
|
||||
.setTokenStatusTransitions(
|
||||
@@ -364,6 +365,7 @@ class DomainCheckFlowTest extends ResourceCheckFlowTestCase<DomainCheckFlow, Dom
|
||||
.setTokenType(UNLIMITED_USE)
|
||||
.setDiscountFraction(0.5)
|
||||
.setDiscountYears(2)
|
||||
.setAllowedEppActions(ImmutableSet.of(CommandName.CREATE))
|
||||
.setTokenStatusTransitions(
|
||||
ImmutableSortedMap.<DateTime, TokenStatus>naturalOrder()
|
||||
.put(START_OF_TIME, TokenStatus.NOT_STARTED)
|
||||
|
||||
@@ -30,6 +30,7 @@ import google.registry.flows.certs.CertificateChecker;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.testing.CertificateSamples;
|
||||
import google.registry.util.CidrAddressBlock;
|
||||
import java.net.InetAddress;
|
||||
import java.util.Optional;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -42,10 +43,14 @@ public class LoginFlowViaTlsTest extends LoginFlowTestCase {
|
||||
Optional.of(CertificateSamples.SAMPLE_CERT3_HASH);
|
||||
private static final Optional<String> BAD_CERT_HASH =
|
||||
Optional.of(CertificateSamples.SAMPLE_CERT2_HASH);
|
||||
private static final Optional<String> GOOD_IP = Optional.of("192.168.1.1");
|
||||
private static final Optional<String> BAD_IP = Optional.of("1.1.1.1");
|
||||
private static final Optional<String> GOOD_IPV6 = Optional.of("2001:db8::1");
|
||||
private static final Optional<String> BAD_IPV6 = Optional.of("2001:db8::2");
|
||||
private static final Optional<InetAddress> GOOD_IP =
|
||||
Optional.of(InetAddresses.forString("192.168.1.1"));
|
||||
private static final Optional<InetAddress> BAD_IP =
|
||||
Optional.of(InetAddresses.forString("1.1.1.1"));
|
||||
private static final Optional<InetAddress> GOOD_IPV6 =
|
||||
Optional.of(InetAddresses.forString("2001:db8::1"));
|
||||
private static final Optional<InetAddress> BAD_IPV6 =
|
||||
Optional.of(InetAddresses.forString("2001:db8::2"));
|
||||
private final CertificateChecker certificateChecker =
|
||||
new CertificateChecker(
|
||||
ImmutableSortedMap.of(START_OF_TIME, 825, DateTime.parse("2020-09-01T00:00:00Z"), 398),
|
||||
@@ -59,8 +64,7 @@ public class LoginFlowViaTlsTest extends LoginFlowTestCase {
|
||||
protected Registrar.Builder getRegistrarBuilder() {
|
||||
return super.getRegistrarBuilder()
|
||||
.setClientCertificate(GOOD_CERT.get(), DateTime.now(UTC))
|
||||
.setIpAddressAllowList(
|
||||
ImmutableList.of(CidrAddressBlock.create(InetAddresses.forString(GOOD_IP.get()), 32)));
|
||||
.setIpAddressAllowList(ImmutableList.of(CidrAddressBlock.create(GOOD_IP.get(), 32)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -129,7 +133,7 @@ public class LoginFlowViaTlsTest extends LoginFlowTestCase {
|
||||
CidrAddressBlock.create(InetAddresses.forString("192.168.1.1"), 32),
|
||||
CidrAddressBlock.create(InetAddresses.forString("2001:db8::1"), 128)))
|
||||
.build());
|
||||
credentials = new TlsCredentials(true, GOOD_CERT_HASH, GOOD_CERT, certificateChecker);
|
||||
credentials = new TlsCredentials(true, GOOD_CERT_HASH, Optional.empty(), certificateChecker);
|
||||
doFailingTest("login_valid.xml", BadRegistrarIpAddressException.class);
|
||||
}
|
||||
|
||||
|
||||
@@ -219,10 +219,10 @@ public abstract class JpaTransactionManagerExtension
|
||||
recreateSchema();
|
||||
}
|
||||
JpaTransactionManagerImpl txnManager = new JpaTransactionManagerImpl(emf, clock);
|
||||
JpaTransactionManagerImpl readOnlyTxnManager = new JpaTransactionManagerImpl(emf, clock, true);
|
||||
cachedTm = TransactionManagerFactory.tm();
|
||||
TransactionManagerFactory.setJpaTm(Suppliers.ofInstance(txnManager));
|
||||
TransactionManagerFactory.setReplicaJpaTm(
|
||||
Suppliers.ofInstance(new ReplicaSimulatingJpaTransactionManager(txnManager)));
|
||||
TransactionManagerFactory.setReplicaJpaTm(Suppliers.ofInstance(readOnlyTxnManager));
|
||||
// Reset SQL Sequence based id allocation so that ids are deterministic in tests.
|
||||
TransactionManagerFactory.tm()
|
||||
.transact(
|
||||
|
||||
@@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.persistence.PersistenceModule.TransactionIsolationLevel.TRANSACTION_READ_COMMITTED;
|
||||
import static google.registry.persistence.PersistenceModule.TransactionIsolationLevel.TRANSACTION_READ_UNCOMMITTED;
|
||||
import static google.registry.persistence.PersistenceModule.TransactionIsolationLevel.TRANSACTION_REPEATABLE_READ;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.replicaTm;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.testing.DatabaseHelper.assertDetachedFromEntityManager;
|
||||
import static google.registry.testing.DatabaseHelper.existsInDb;
|
||||
@@ -107,6 +108,44 @@ class JpaTransactionManagerImplTest {
|
||||
assertCompanyExist("Bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
void transact_replica_failureOnWrite() {
|
||||
assertPersonEmpty();
|
||||
assertCompanyEmpty();
|
||||
DatabaseException thrown =
|
||||
assertThrows(
|
||||
DatabaseException.class,
|
||||
() ->
|
||||
replicaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
insertPerson(10);
|
||||
}));
|
||||
assertThat(thrown)
|
||||
.hasMessageThat()
|
||||
.contains("cannot execute INSERT in a read-only transaction");
|
||||
}
|
||||
|
||||
@Test
|
||||
void transact_replica_successOnRead() {
|
||||
assertPersonEmpty();
|
||||
assertCompanyEmpty();
|
||||
tm().transact(
|
||||
() -> {
|
||||
insertPerson(10);
|
||||
});
|
||||
replicaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
EntityManager em = replicaTm().getEntityManager();
|
||||
Integer maybeAge =
|
||||
(Integer)
|
||||
em.createNativeQuery("SELECT age FROM Person WHERE age = 10")
|
||||
.getSingleResult();
|
||||
assertThat(maybeAge).isEqualTo(10);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void transact_setIsolationLevel() {
|
||||
// If not specified, run at the default isolation level.
|
||||
|
||||
@@ -1,289 +0,0 @@
|
||||
// Copyright 2022 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package google.registry.persistence.transaction;
|
||||
|
||||
import static com.google.common.base.Throwables.throwIfUnchecked;
|
||||
import static google.registry.persistence.transaction.DatabaseException.throwIfSqlException;
|
||||
|
||||
import com.google.common.collect.ImmutableCollection;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.persistence.PersistenceModule.TransactionIsolationLevel;
|
||||
import google.registry.persistence.VKey;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.stream.Stream;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* A {@link JpaTransactionManager} that simulates a read-only replica SQL instance.
|
||||
*
|
||||
* <p>We accomplish this by delegating all calls to the standard transaction manager except for
|
||||
* calls that start transactions. For these, we create a transaction like normal but set it to READ
|
||||
* ONLY mode before doing any work. This is similar to how the read-only Postgres replica works; it
|
||||
* treats all transactions as read-only transactions.
|
||||
*/
|
||||
public class ReplicaSimulatingJpaTransactionManager implements JpaTransactionManager {
|
||||
|
||||
private final JpaTransactionManager delegate;
|
||||
|
||||
public ReplicaSimulatingJpaTransactionManager(JpaTransactionManager delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teardown() {
|
||||
delegate.teardown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionIsolationLevel getDefaultTransactionIsolationLevel() {
|
||||
return delegate.getDefaultTransactionIsolationLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionIsolationLevel getCurrentTransactionIsolationLevel() {
|
||||
return delegate.getCurrentTransactionIsolationLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityManager getStandaloneEntityManager() {
|
||||
return delegate.getStandaloneEntityManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityManager getEntityManager() {
|
||||
return delegate.getEntityManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> TypedQuery<T> query(String sqlString, Class<T> resultClass) {
|
||||
return delegate.query(sqlString, resultClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> TypedQuery<T> criteriaQuery(CriteriaQuery<T> criteriaQuery) {
|
||||
return delegate.criteriaQuery(criteriaQuery);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query query(String sqlString) {
|
||||
return delegate.query(sqlString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inTransaction() {
|
||||
return delegate.inTransaction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assertInTransaction() {
|
||||
delegate.assertInTransaction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T transact(Callable<T> work, TransactionIsolationLevel isolationLevel) {
|
||||
if (inTransaction()) {
|
||||
try {
|
||||
return work.call();
|
||||
} catch (Exception e) {
|
||||
throwIfSqlException(e);
|
||||
throwIfUnchecked(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return delegate.transact(
|
||||
() -> {
|
||||
delegate
|
||||
.getEntityManager()
|
||||
.createNativeQuery("SET TRANSACTION READ ONLY")
|
||||
.executeUpdate();
|
||||
return work.call();
|
||||
},
|
||||
isolationLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T reTransact(Callable<T> work) {
|
||||
return transact(work);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T transact(Callable<T> work) {
|
||||
return transact(work, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transact(ThrowingRunnable work, TransactionIsolationLevel isolationLevel) {
|
||||
transact(
|
||||
() -> {
|
||||
work.run();
|
||||
return null;
|
||||
},
|
||||
isolationLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reTransact(ThrowingRunnable work) {
|
||||
transact(work);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transact(ThrowingRunnable work) {
|
||||
transact(work, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DateTime getTransactionTime() {
|
||||
return delegate.getTransactionTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insert(Object entity) {
|
||||
delegate.insert(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertAll(ImmutableCollection<?> entities) {
|
||||
delegate.insertAll(entities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertAll(ImmutableObject... entities) {
|
||||
delegate.insertAll(entities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(Object entity) {
|
||||
delegate.put(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(ImmutableObject... entities) {
|
||||
delegate.putAll(entities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(ImmutableCollection<?> entities) {
|
||||
delegate.putAll(entities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Object entity) {
|
||||
delegate.update(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAll(ImmutableCollection<?> entities) {
|
||||
delegate.updateAll(entities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAll(ImmutableObject... entities) {
|
||||
delegate.updateAll(entities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> boolean exists(VKey<T> key) {
|
||||
return delegate.exists(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists(Object entity) {
|
||||
return delegate.exists(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Optional<T> loadByKeyIfPresent(VKey<T> key) {
|
||||
return delegate.loadByKeyIfPresent(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ImmutableMap<VKey<? extends T>, T> loadByKeysIfPresent(
|
||||
Iterable<? extends VKey<? extends T>> vKeys) {
|
||||
return delegate.loadByKeysIfPresent(vKeys);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ImmutableList<T> loadByEntitiesIfPresent(Iterable<T> entities) {
|
||||
return delegate.loadByEntitiesIfPresent(entities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T loadByKey(VKey<T> key) {
|
||||
return delegate.loadByKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ImmutableMap<VKey<? extends T>, T> loadByKeys(
|
||||
Iterable<? extends VKey<? extends T>> vKeys) {
|
||||
return delegate.loadByKeys(vKeys);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T loadByEntity(T entity) {
|
||||
return delegate.loadByEntity(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ImmutableList<T> loadByEntities(Iterable<T> entities) {
|
||||
return delegate.loadByEntities(entities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ImmutableList<T> loadAllOf(Class<T> clazz) {
|
||||
return delegate.loadAllOf(clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Stream<T> loadAllOfStream(Class<T> clazz) {
|
||||
return delegate.loadAllOfStream(clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Optional<T> loadSingleton(Class<T> clazz) {
|
||||
return delegate.loadSingleton(clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(VKey<?> key) {
|
||||
delegate.delete(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Iterable<? extends VKey<?>> vKeys) {
|
||||
delegate.delete(vKeys);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T delete(T entity) {
|
||||
return delegate.delete(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> QueryComposer<T> createQueryComposer(Class<T> entity) {
|
||||
return delegate.createQueryComposer(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void assertDelete(VKey<T> key) {
|
||||
delegate.assertDelete(key);
|
||||
}
|
||||
}
|
||||
@@ -263,7 +263,7 @@ public class RdeReportActionTest {
|
||||
@Test
|
||||
void testRunWithLock_badRequest_throws500WithErrorInfo() throws Exception {
|
||||
when(httpUrlConnection.getResponseCode()).thenReturn(STATUS_CODE_BAD_REQUEST);
|
||||
when(httpUrlConnection.getInputStream()).thenReturn(IIRDEA_BAD_XML.openBufferedStream());
|
||||
when(httpUrlConnection.getErrorStream()).thenReturn(IIRDEA_BAD_XML.openBufferedStream());
|
||||
InternalServerErrorException thrown =
|
||||
assertThrows(
|
||||
InternalServerErrorException.class,
|
||||
|
||||
@@ -99,10 +99,10 @@ class IcannHttpReporterTest {
|
||||
|
||||
@Test
|
||||
void testFail_BadIirdeaResponse() throws Exception {
|
||||
when(connection.getInputStream()).thenReturn(IIRDEA_BAD_XML.openBufferedStream());
|
||||
when(connection.getResponseCode()).thenReturn(STATUS_CODE_BAD_REQUEST);
|
||||
when(connection.getErrorStream()).thenReturn(IIRDEA_BAD_XML.openBufferedStream());
|
||||
assertThat(reporter.send(FAKE_PAYLOAD, "test-transactions-201706.csv")).isFalse();
|
||||
verify(connection).getInputStream();
|
||||
verify(connection).getErrorStream();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -29,6 +29,7 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -104,4 +105,21 @@ public class UrlConnectionUtilsTest {
|
||||
"Multipart data contains autogenerated boundary: "
|
||||
+ "------------------------------AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testErrorStream() throws Exception {
|
||||
HttpsURLConnection connection = mock(HttpsURLConnection.class);
|
||||
when(connection.getResponseCode()).thenReturn(400);
|
||||
when(connection.getErrorStream())
|
||||
.thenReturn(new ByteArrayInputStream("Failure".getBytes(UTF_8)));
|
||||
assertThat(UrlConnectionUtils.getResponseBytes(connection))
|
||||
.isEqualTo("Failure".getBytes(UTF_8));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testErrorStream_null() throws Exception {
|
||||
HttpsURLConnection connection = mock(HttpsURLConnection.class);
|
||||
when(connection.getResponseCode()).thenReturn(400);
|
||||
assertThat(UrlConnectionUtils.getResponseBytes(connection)).isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,6 +108,8 @@ class NordnUploadActionTest {
|
||||
void beforeEach() throws Exception {
|
||||
when(httpUrlConnection.getInputStream())
|
||||
.thenReturn(new ByteArrayInputStream("Success".getBytes(UTF_8)));
|
||||
when(httpUrlConnection.getErrorStream())
|
||||
.thenReturn(new ByteArrayInputStream("Failure".getBytes(UTF_8)));
|
||||
when(httpUrlConnection.getResponseCode()).thenReturn(SC_ACCEPTED);
|
||||
when(httpUrlConnection.getHeaderField(LOCATION)).thenReturn("http://trololol");
|
||||
when(httpUrlConnection.getOutputStream()).thenReturn(connectionOutputStream);
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
package google.registry.tools;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.google.common.truth.Truth8.assertThat;
|
||||
import static google.registry.model.EntityYamlUtils.createObjectMapper;
|
||||
import static google.registry.model.domain.token.AllocationToken.TokenType.DEFAULT_PROMO;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.testing.DatabaseHelper.createTld;
|
||||
import static google.registry.testing.DatabaseHelper.persistPremiumList;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
@@ -46,6 +46,7 @@ import google.registry.model.tld.Tld.TldNotFoundException;
|
||||
import google.registry.model.tld.label.PremiumList;
|
||||
import google.registry.model.tld.label.PremiumListDao;
|
||||
import java.io.File;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Logger;
|
||||
import org.joda.money.Money;
|
||||
import org.joda.time.DateTime;
|
||||
@@ -101,20 +102,19 @@ public class ConfigureTldCommandTest extends CommandTestCase<ConfigureTldCommand
|
||||
assertThat(updatedTld.getCreateBillingCost()).isEqualTo(Money.of(USD, 25));
|
||||
testTldConfiguredSuccessfully(updatedTld, "tld.yaml");
|
||||
assertThat(updatedTld.getBreakglassMode()).isFalse();
|
||||
assertThat(tld.getBsaEnrollStartTime()).isNull();
|
||||
assertThat(tld.getBsaEnrollStartTime()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_updateTld_bsaTimeUnaffected() throws Exception {
|
||||
void testSuccess_updateTld_existingBsaTimeCarriedOver() throws Exception {
|
||||
Tld tld = createTld("tld");
|
||||
DateTime bsaStartTime = DateTime.now(DateTimeZone.UTC);
|
||||
tm().transact(() -> tm().put(tld.asBuilder().setBsaEnrollStartTime(bsaStartTime).build()));
|
||||
persistResource(tld.asBuilder().setBsaEnrollStartTime(Optional.of(bsaStartTime)).build());
|
||||
File tldFile = tmpDir.resolve("tld.yaml").toFile();
|
||||
Files.asCharSink(tldFile, UTF_8).write(loadFile(getClass(), "tld.yaml"));
|
||||
runCommandForced("--input=" + tldFile);
|
||||
// TODO(11/30/2023): uncomment below two lines
|
||||
// Tld updatedTld = Tld.get("tld");
|
||||
// assertThat(tld.getBsaEnrollStartTime()).isEqualTo(bsaStartTime);
|
||||
Tld updatedTld = Tld.get("tld");
|
||||
assertThat(updatedTld.getBsaEnrollStartTime()).hasValue(bsaStartTime);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -53,6 +53,7 @@ abstract class CreateOrUpdateReservedListCommandTestCase<
|
||||
.write("sdfgagmsdgs,sdfgsd\nasdf234tafgs,asdfaw\n\n");
|
||||
reservedTermsPath = reservedTermsFile.getPath();
|
||||
invalidReservedTermsPath = invalidReservedTermsFile.getPath();
|
||||
command.printStream = System.out;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -66,6 +66,8 @@ class UpdateReservedListCommandTest
|
||||
assertThat(ReservedList.get("xn--q9jyb4c_common-reserved")).isPresent();
|
||||
ReservedList reservedList = ReservedList.get("xn--q9jyb4c_common-reserved").get();
|
||||
assertThat(reservedList.getShouldPublish()).isFalse();
|
||||
assertInStdout("Update reserved list for xn--q9jyb4c_common-reserved?");
|
||||
assertInStdout("shouldPublish: true -> false");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -85,6 +87,10 @@ class UpdateReservedListCommandTest
|
||||
assertThat(reservedList.getReservationInList("baddies")).hasValue(FULLY_BLOCKED);
|
||||
assertThat(reservedList.getReservationInList("ford")).hasValue(FULLY_BLOCKED);
|
||||
assertThat(reservedList.getReservationInList("helicopter")).isEmpty();
|
||||
assertInStdout("Update reserved list for xn--q9jyb4c_common-reserved?");
|
||||
assertInStdout("helicopter: helicopter,FULLY_BLOCKED -> null");
|
||||
assertInStdout("baddies: null -> baddies,FULLY_BLOCKED");
|
||||
assertInStdout("ford: null -> ford,FULLY_BLOCKED # random comment");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -127,11 +133,13 @@ class UpdateReservedListCommandTest
|
||||
// CreateOrUpdateReservedListCommandTestCases.java
|
||||
UpdateReservedListCommand command = new UpdateReservedListCommand();
|
||||
command.input = Paths.get(reservedTermsPath);
|
||||
command.shouldPublish = false;
|
||||
command.init();
|
||||
|
||||
assertThat(command.prompt()).contains("Update reserved list for xn--q9jyb4c_common-reserved?");
|
||||
assertThat(command.prompt()).contains("Old list: [(helicopter,FULLY_BLOCKED)]");
|
||||
assertThat(command.prompt())
|
||||
.contains("New list: [(baddies,FULLY_BLOCKED), (ford,FULLY_BLOCKED # random comment)]");
|
||||
assertThat(command.prompt()).contains("shouldPublish: true -> false");
|
||||
assertThat(command.prompt()).contains("helicopter: helicopter,FULLY_BLOCKED -> null");
|
||||
assertThat(command.prompt()).contains("baddies: null -> baddies,FULLY_BLOCKED");
|
||||
assertThat(command.prompt()).contains("ford: null -> ford,FULLY_BLOCKED # random comment");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import static google.registry.testing.DatabaseHelper.persistActiveDomain;
|
||||
import static google.registry.testing.DatabaseHelper.persistDomainAsDeleted;
|
||||
|
||||
import com.google.api.client.http.HttpStatusCodes;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.gson.Gson;
|
||||
import google.registry.model.EppResourceUtils;
|
||||
import google.registry.model.console.GlobalRole;
|
||||
@@ -90,7 +91,7 @@ public class ConsoleDomainListActionTest {
|
||||
@Test
|
||||
void testSuccess_pages() {
|
||||
// Two pages of results should go in reverse chronological order
|
||||
ConsoleDomainListAction action = createAction("TheRegistrar", null, 0, 5, null);
|
||||
ConsoleDomainListAction action = createAction("TheRegistrar", null, 0, 5, null, null);
|
||||
action.run();
|
||||
DomainListResult result = GSON.fromJson(response.getPayload(), DomainListResult.class);
|
||||
assertThat(result.domains.stream().map(Domain::getDomainName).collect(toImmutableList()))
|
||||
@@ -98,7 +99,7 @@ public class ConsoleDomainListActionTest {
|
||||
assertThat(result.totalResults).isEqualTo(10);
|
||||
|
||||
// Now do the second page
|
||||
action = createAction("TheRegistrar", result.checkpointTime, 1, 5, 10L);
|
||||
action = createAction("TheRegistrar", result.checkpointTime, 1, 5, 10L, null);
|
||||
action.run();
|
||||
result = GSON.fromJson(response.getPayload(), DomainListResult.class);
|
||||
assertThat(result.domains.stream().map(Domain::getDomainName).collect(toImmutableList()))
|
||||
@@ -107,7 +108,7 @@ public class ConsoleDomainListActionTest {
|
||||
|
||||
@Test
|
||||
void testSuccess_partialPage() {
|
||||
ConsoleDomainListAction action = createAction("TheRegistrar", null, 1, 8, null);
|
||||
ConsoleDomainListAction action = createAction("TheRegistrar", null, 1, 8, null, null);
|
||||
action.run();
|
||||
DomainListResult result = GSON.fromJson(response.getPayload(), DomainListResult.class);
|
||||
assertThat(result.domains.stream().map(Domain::getDomainName).collect(toImmutableList()))
|
||||
@@ -116,7 +117,7 @@ public class ConsoleDomainListActionTest {
|
||||
|
||||
@Test
|
||||
void testSuccess_checkpointTime_createdBefore() {
|
||||
ConsoleDomainListAction action = createAction("TheRegistrar", null, 0, 10, null);
|
||||
ConsoleDomainListAction action = createAction("TheRegistrar", null, 0, 10, null, null);
|
||||
action.run();
|
||||
|
||||
DomainListResult result = GSON.fromJson(response.getPayload(), DomainListResult.class);
|
||||
@@ -127,7 +128,7 @@ public class ConsoleDomainListActionTest {
|
||||
persistActiveDomain("newdomain.tld", clock.nowUtc());
|
||||
|
||||
// Even though we persisted a new domain, the old checkpoint should return no more results
|
||||
action = createAction("TheRegistrar", result.checkpointTime, 1, 10, null);
|
||||
action = createAction("TheRegistrar", result.checkpointTime, 1, 10, null, null);
|
||||
action.run();
|
||||
result = GSON.fromJson(response.getPayload(), DomainListResult.class);
|
||||
assertThat(result.domains).isEmpty();
|
||||
@@ -136,7 +137,7 @@ public class ConsoleDomainListActionTest {
|
||||
|
||||
@Test
|
||||
void testSuccess_checkpointTime_deletion() {
|
||||
ConsoleDomainListAction action = createAction("TheRegistrar", null, 0, 5, null);
|
||||
ConsoleDomainListAction action = createAction("TheRegistrar", null, 0, 5, null, null);
|
||||
action.run();
|
||||
DomainListResult result = GSON.fromJson(response.getPayload(), DomainListResult.class);
|
||||
|
||||
@@ -146,16 +147,50 @@ public class ConsoleDomainListActionTest {
|
||||
persistDomainAsDeleted(toDelete, clock.nowUtc());
|
||||
|
||||
// Second page should include the domain that is now deleted due to the checkpoint time
|
||||
action = createAction("TheRegistrar", result.checkpointTime, 1, 5, null);
|
||||
action = createAction("TheRegistrar", result.checkpointTime, 1, 5, null, null);
|
||||
action.run();
|
||||
result = GSON.fromJson(response.getPayload(), DomainListResult.class);
|
||||
assertThat(result.domains.stream().map(Domain::getDomainName).collect(toImmutableList()))
|
||||
.containsExactly("4exists.tld", "3exists.tld", "2exists.tld", "1exists.tld", "0exists.tld");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_searchTerm_oneMatch() {
|
||||
ConsoleDomainListAction action = createAction("TheRegistrar", null, 0, 5, null, "0");
|
||||
action.run();
|
||||
DomainListResult result = GSON.fromJson(response.getPayload(), DomainListResult.class);
|
||||
assertThat(Iterables.getOnlyElement(result.domains).getDomainName()).isEqualTo("0exists.tld");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_searchTerm_returnsNone() {
|
||||
ConsoleDomainListAction action = createAction("TheRegistrar", null, 0, 5, null, "deleted");
|
||||
action.run();
|
||||
DomainListResult result = GSON.fromJson(response.getPayload(), DomainListResult.class);
|
||||
assertThat(result.domains).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_searchTerm_caseInsensitive() {
|
||||
ConsoleDomainListAction action = createAction("TheRegistrar", null, 0, 5, null, "eXiStS");
|
||||
action.run();
|
||||
DomainListResult result = GSON.fromJson(response.getPayload(), DomainListResult.class);
|
||||
assertThat(result.domains).hasSize(5);
|
||||
assertThat(result.totalResults).isEqualTo(10);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_searchTerm_tld() {
|
||||
ConsoleDomainListAction action = createAction("TheRegistrar", null, 0, 5, null, "tld");
|
||||
action.run();
|
||||
DomainListResult result = GSON.fromJson(response.getPayload(), DomainListResult.class);
|
||||
assertThat(result.domains).hasSize(5);
|
||||
assertThat(result.totalResults).isEqualTo(10);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPartialSuccess_pastEnd() {
|
||||
ConsoleDomainListAction action = createAction("TheRegistrar", null, 5, 5, null);
|
||||
ConsoleDomainListAction action = createAction("TheRegistrar", null, 5, 5, null, null);
|
||||
action.run();
|
||||
DomainListResult result = GSON.fromJson(response.getPayload(), DomainListResult.class);
|
||||
assertThat(result.domains).isEmpty();
|
||||
@@ -163,13 +198,13 @@ public class ConsoleDomainListActionTest {
|
||||
|
||||
@Test
|
||||
void testFailure_invalidResultsPerPage() {
|
||||
ConsoleDomainListAction action = createAction("TheRegistrar", null, 0, 0, null);
|
||||
ConsoleDomainListAction action = createAction("TheRegistrar", null, 0, 0, null, null);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(response.getPayload())
|
||||
.isEqualTo("Results per page must be between 1 and 500 inclusive");
|
||||
|
||||
action = createAction("TheRegistrar", null, 0, 501, null);
|
||||
action = createAction("TheRegistrar", null, 0, 501, null, null);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(response.getPayload())
|
||||
@@ -178,14 +213,14 @@ public class ConsoleDomainListActionTest {
|
||||
|
||||
@Test
|
||||
void testFailure_invalidPageNumber() {
|
||||
ConsoleDomainListAction action = createAction("TheRegistrar", null, -1, 10, null);
|
||||
ConsoleDomainListAction action = createAction("TheRegistrar", null, -1, 10, null, null);
|
||||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_BAD_REQUEST);
|
||||
assertThat(response.getPayload()).isEqualTo("Page number must be non-negative");
|
||||
}
|
||||
|
||||
private ConsoleDomainListAction createAction(String registrarId) {
|
||||
return createAction(registrarId, null, null, null, null);
|
||||
return createAction(registrarId, null, null, null, null, null);
|
||||
}
|
||||
|
||||
private ConsoleDomainListAction createAction(
|
||||
@@ -193,7 +228,8 @@ public class ConsoleDomainListActionTest {
|
||||
@Nullable DateTime checkpointTime,
|
||||
@Nullable Integer pageNumber,
|
||||
@Nullable Integer resultsPerPage,
|
||||
@Nullable Long totalResults) {
|
||||
@Nullable Long totalResults,
|
||||
@Nullable String searchTerm) {
|
||||
response = new FakeResponse();
|
||||
AuthResult authResult =
|
||||
AuthResult.createUser(
|
||||
@@ -210,6 +246,7 @@ public class ConsoleDomainListActionTest {
|
||||
Optional.ofNullable(checkpointTime),
|
||||
Optional.ofNullable(pageNumber),
|
||||
Optional.ofNullable(resultsPerPage),
|
||||
Optional.ofNullable(totalResults));
|
||||
Optional.ofNullable(totalResults),
|
||||
Optional.ofNullable(searchTerm));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,24 @@
|
||||
<fee:command>create</fee:command>
|
||||
<fee:period unit="y">1</fee:period>
|
||||
</fee:domain>
|
||||
<fee:domain>
|
||||
<fee:name>example1.tld</fee:name>
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:command>renew</fee:command>
|
||||
<fee:period unit="y">1</fee:period>
|
||||
</fee:domain>
|
||||
<fee:domain>
|
||||
<fee:name>example2.example</fee:name>
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:command>renew</fee:command>
|
||||
<fee:period unit="y">1</fee:period>
|
||||
</fee:domain>
|
||||
<fee:domain>
|
||||
<fee:name>reserved.tld</fee:name>
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:command>renew</fee:command>
|
||||
<fee:period unit="y">1</fee:period>
|
||||
</fee:domain>
|
||||
</fee:check>
|
||||
</extension>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
|
||||
@@ -42,6 +42,28 @@
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:class>token-not-supported</fee:class>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:name>example1.tld</fee:name>
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:command>renew</fee:command>
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:fee description="renew">11.00</fee:fee>
|
||||
<fee:class>premium</fee:class>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:name>example2.example</fee:name>
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:command>renew</fee:command>
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:class>token-not-supported</fee:class>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:name>reserved.tld</fee:name>
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:command>renew</fee:command>
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:class>token-not-supported</fee:class>
|
||||
</fee:cd>
|
||||
</fee:chkData>
|
||||
</extension>
|
||||
<trID>
|
||||
|
||||
@@ -41,6 +41,27 @@
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:class>reserved</fee:class>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:name>example1.tld</fee:name>
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:command>renew</fee:command>
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:class>token-not-supported</fee:class>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:name>example2.example</fee:name>
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:command>renew</fee:command>
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:class>token-not-supported</fee:class>
|
||||
</fee:cd>
|
||||
<fee:cd>
|
||||
<fee:name>reserved.tld</fee:name>
|
||||
<fee:currency>USD</fee:currency>
|
||||
<fee:command>renew</fee:command>
|
||||
<fee:period unit="y">1</fee:period>
|
||||
<fee:class>token-not-supported</fee:class>
|
||||
</fee:cd>
|
||||
</fee:chkData>
|
||||
</extension>
|
||||
<trID>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -148,3 +148,5 @@ V147__drop_gaia_id_from_user.sql
|
||||
V148__add_bsa_download_and_label_tables.sql
|
||||
V149__add_bsa_domain_in_use_table.sql
|
||||
V150__add_tld_bsa_enroll_date.sql
|
||||
V151__add_bsa_unblockable_domain_table.sql
|
||||
V152__add_bsa_domain_refresh_table.sql
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
-- Copyright 2023 The Nomulus Authors. All Rights Reserved.
|
||||
--
|
||||
-- Licensed under the Apache License, Version 2.0 (the "License");
|
||||
-- you may not use this file except in compliance with the License.
|
||||
-- You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing, software
|
||||
-- distributed under the License is distributed on an "AS IS" BASIS,
|
||||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
-- See the License for the specific language governing permissions and
|
||||
-- limitations under the License.
|
||||
|
||||
CREATE TABLE "BsaUnblockableDomain" (
|
||||
label text not null,
|
||||
tld text not null,
|
||||
creation_time timestamptz not null,
|
||||
reason text not null,
|
||||
primary key (label, tld)
|
||||
);
|
||||
|
||||
ALTER TABLE IF EXISTS "BsaUnblockableDomain"
|
||||
ADD CONSTRAINT FKbsaunblockabledomainlabel
|
||||
FOREIGN KEY (label)
|
||||
REFERENCES "BsaLabel" (label)
|
||||
ON DELETE CASCADE;
|
||||
@@ -0,0 +1,21 @@
|
||||
-- Copyright 2023 The Nomulus Authors. All Rights Reserved.
|
||||
--
|
||||
-- Licensed under the Apache License, Version 2.0 (the "License");
|
||||
-- you may not use this file except in compliance with the License.
|
||||
-- You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing, software
|
||||
-- distributed under the License is distributed on an "AS IS" BASIS,
|
||||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
-- See the License for the specific language governing permissions and
|
||||
-- limitations under the License.
|
||||
|
||||
CREATE TABLE "BsaDomainRefresh" (
|
||||
job_id bigserial not null,
|
||||
creation_time timestamptz not null,
|
||||
stage text not null,
|
||||
update_timestamp timestamptz,
|
||||
primary key (job_id)
|
||||
);
|
||||
@@ -728,6 +728,7 @@
|
||||
auto_renew_grace_period_length interval not null,
|
||||
automatic_transfer_length interval not null,
|
||||
breakglass_mode boolean not null,
|
||||
bsa_enroll_start_time timestamptz,
|
||||
claims_period_end timestamptz not null,
|
||||
create_billing_cost_amount numeric(19, 2),
|
||||
create_billing_cost_currency text,
|
||||
|
||||
@@ -135,6 +135,37 @@ CREATE TABLE public."BsaDomainInUse" (
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: BsaDomainRefresh; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public."BsaDomainRefresh" (
|
||||
job_id bigint NOT NULL,
|
||||
creation_time timestamp with time zone NOT NULL,
|
||||
stage text NOT NULL,
|
||||
update_timestamp timestamp with time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: BsaDomainRefresh_job_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public."BsaDomainRefresh_job_id_seq"
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: BsaDomainRefresh_job_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public."BsaDomainRefresh_job_id_seq" OWNED BY public."BsaDomainRefresh".job_id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: BsaDownload; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
@@ -177,6 +208,18 @@ CREATE TABLE public."BsaLabel" (
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: BsaUnblockableDomain; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public."BsaUnblockableDomain" (
|
||||
label text NOT NULL,
|
||||
tld text NOT NULL,
|
||||
creation_time timestamp with time zone NOT NULL,
|
||||
reason text NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: ClaimsEntry; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
@@ -1210,6 +1253,13 @@ CREATE SEQUENCE public.project_wide_unique_id_seq
|
||||
CACHE 10;
|
||||
|
||||
|
||||
--
|
||||
-- Name: BsaDomainRefresh job_id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."BsaDomainRefresh" ALTER COLUMN job_id SET DEFAULT nextval('public."BsaDomainRefresh_job_id_seq"'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: BsaDownload job_id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
@@ -1327,6 +1377,14 @@ ALTER TABLE ONLY public."BsaDomainInUse"
|
||||
ADD CONSTRAINT "BsaDomainInUse_pkey" PRIMARY KEY (label, tld);
|
||||
|
||||
|
||||
--
|
||||
-- Name: BsaDomainRefresh BsaDomainRefresh_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."BsaDomainRefresh"
|
||||
ADD CONSTRAINT "BsaDomainRefresh_pkey" PRIMARY KEY (job_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: BsaDownload BsaDownload_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
@@ -1343,6 +1401,14 @@ ALTER TABLE ONLY public."BsaLabel"
|
||||
ADD CONSTRAINT "BsaLabel_pkey" PRIMARY KEY (label);
|
||||
|
||||
|
||||
--
|
||||
-- Name: BsaUnblockableDomain BsaUnblockableDomain_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."BsaUnblockableDomain"
|
||||
ADD CONSTRAINT "BsaUnblockableDomain_pkey" PRIMARY KEY (label, tld);
|
||||
|
||||
|
||||
--
|
||||
-- Name: ClaimsEntry ClaimsEntry_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
@@ -2723,6 +2789,14 @@ ALTER TABLE ONLY public."BsaDomainInUse"
|
||||
ADD CONSTRAINT fkbsadomaininuse2label FOREIGN KEY (label) REFERENCES public."BsaLabel"(label) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: BsaUnblockableDomain fkbsaunblockabledomainlabel; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."BsaUnblockableDomain"
|
||||
ADD CONSTRAINT fkbsaunblockabledomainlabel FOREIGN KEY (label) REFERENCES public."BsaLabel"(label) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: DomainTransactionRecord fkcjqe54u72kha71vkibvxhjye7; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
@@ -124,6 +124,7 @@ public class EppServiceHandler extends HttpsRelayServiceHandler {
|
||||
.headers()
|
||||
.set(ProxyHttpHeaders.CERTIFICATE_HASH, sslClientCertificateHash)
|
||||
.set(ProxyHttpHeaders.IP_ADDRESS, clientAddress)
|
||||
.set(ProxyHttpHeaders.FALLBACK_IP_ADDRESS, clientAddress)
|
||||
.set(HttpHeaderNames.CONTENT_TYPE, EPP_CONTENT_TYPE)
|
||||
.set(HttpHeaderNames.ACCEPT, EPP_CONTENT_TYPE);
|
||||
return request;
|
||||
|
||||
@@ -100,7 +100,8 @@ public final class TestUtils {
|
||||
.set(HttpHeaderNames.CONTENT_TYPE, "application/epp+xml")
|
||||
.set("accept", "application/epp+xml")
|
||||
.set(ProxyHttpHeaders.CERTIFICATE_HASH, sslClientCertificateHash)
|
||||
.set(ProxyHttpHeaders.IP_ADDRESS, clientAddress);
|
||||
.set(ProxyHttpHeaders.IP_ADDRESS, clientAddress)
|
||||
.set(ProxyHttpHeaders.FALLBACK_IP_ADDRESS, clientAddress);
|
||||
if (cookies.length != 0) {
|
||||
request.headers().set("cookie", ClientCookieEncoder.STRICT.encode(cookies));
|
||||
}
|
||||
|
||||
@@ -78,8 +78,8 @@ steps:
|
||||
grep -e "^backend\|^default\|^bsa\|^pubapi\|^tools" |\
|
||||
while read line; do echo "${TAG_NAME},$line"; done | tee "$local_map"
|
||||
num_versions=$(cat "$local_map" | wc -l)
|
||||
if [ "$num_versions" -ne 4 ]; then
|
||||
echo "Expecting exactly four active services. Found $num_versions"
|
||||
if [ "$num_versions" -ne 5 ]; then
|
||||
echo "Expecting exactly five active services. Found $num_versions"
|
||||
exit 1
|
||||
fi
|
||||
gsutil cp "$local_map" gs://$PROJECT_ID-deployed-tags/nomulus.${_ENV}.tmp
|
||||
|
||||
322
services/bsa/gradle.lockfile
Normal file
322
services/bsa/gradle.lockfile
Normal file
@@ -0,0 +1,322 @@
|
||||
# This is a Gradle generated file for dependency locking.
|
||||
# Manual edits can break the build and are not advised.
|
||||
# This file is expected to be part of source control.
|
||||
antlr:antlr:2.7.7=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
aopalliance:aopalliance:1.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
args4j:args4j:2.0.23=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.101tec:zkclient:0.10=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.beust:jcommander:1.60=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson.core:jackson-annotations:2.15.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson.core:jackson-core:2.15.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson.core:jackson-databind:2.15.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson.dataformat:jackson-dataformat-toml:2.15.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.15.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson.datatype:jackson-datatype-joda:2.15.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml.jackson:jackson-bom:2.15.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.fasterxml:classmate:1.5.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.ben-manes.caffeine:caffeine:2.9.3=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.docker-java:docker-java-api:3.3.3=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.docker-java:docker-java-transport-zerodep:3.3.3=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.docker-java:docker-java-transport:3.3.3=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.jnr:jffi:1.3.11=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.jnr:jnr-a64asm:1.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.jnr:jnr-constants:0.10.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.jnr:jnr-enxio:0.32.15=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.jnr:jnr-ffi:2.2.14=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.jnr:jnr-posix:3.1.17=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.jnr:jnr-unixsocket:0.38.20=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.github.jnr:jnr-x86asm:1.0.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.android:annotations:4.1.1.4=runtimeClasspath,testRuntimeClasspath
|
||||
com.google.api-client:google-api-client-appengine:1.35.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api-client:google-api-client-jackson2:2.0.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api-client:google-api-client-java6:1.35.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api-client:google-api-client-servlet:1.35.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api-client:google-api-client:1.35.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:gapic-google-cloud-storage-v2:2.22.6-alpha=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1:2.41.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta1:0.165.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-bigquerystorage-v1beta2:0.165.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-bigtable-v2:2.26.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-pubsub-v1:1.106.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-pubsublite-v1:1.12.13=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-spanner-admin-database-v1:6.45.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-spanner-admin-instance-v1:6.45.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-spanner-v1:6.45.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-cloud-storage-v2:2.23.0-alpha=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:grpc-google-common-protos:2.23.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1:2.41.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1beta1:0.165.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-bigquerystorage-v1beta2:0.165.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-bigtable-admin-v2:2.26.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-bigtable-v2:2.26.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-datastore-v1:0.107.3=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-firestore-v1:3.14.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-monitoring-v3:1.64.0=compileClasspath,testCompileClasspath
|
||||
com.google.api.grpc:proto-google-cloud-monitoring-v3:3.24.0=runtimeClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-pubsub-v1:1.106.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-pubsublite-v1:1.12.13=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-secretmanager-v1:2.23.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-secretmanager-v1beta1:2.23.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-spanner-admin-database-v1:6.45.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-spanner-admin-instance-v1:6.45.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-spanner-v1:6.45.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-storage-v2:2.23.0-alpha=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-tasks-v2:2.23.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-tasks-v2beta2:0.113.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-cloud-tasks-v2beta3:0.113.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-common-protos:2.24.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api.grpc:proto-google-iam-v1:1.18.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api:api-common:2.16.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api:gax-grpc:2.32.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api:gax-httpjson:2.32.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.api:gax:2.33.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-admin-directory:directory_v1-rev118-1.25.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-appengine:v1-rev20230831-2.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-bigquery:v2-rev20230520-2.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-cloudresourcemanager:v1-rev20230129-2.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-dataflow:v1b3-rev20220920-2.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-dns:v2beta1-rev99-1.25.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-drive:v2-rev393-1.25.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-gmail:v1-rev20220404-2.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-groupssettings:v1-rev20210624-2.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-healthcare:v1-rev20230510-2.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-iamcredentials:v1-rev20211203-2.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-monitoring:v3-rev20230806-2.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-pubsub:v1-rev20220904-2.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-sheets:v4-rev20230815-2.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-sqladmin:v1beta4-rev20230831-2.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.apis:google-api-services-storage:v1-rev20230617-2.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.appengine:appengine-api-1.0-sdk:1.9.86=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.appengine:appengine-testing:1.9.86=runtimeClasspath,testRuntimeClasspath
|
||||
com.google.auth:google-auth-library-credentials:1.19.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.auth:google-auth-library-oauth2-http:1.19.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.auto.service:auto-service-annotations:1.1.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.auto.value:auto-value-annotations:1.10.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.auto.value:auto-value:1.10.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud.bigdataoss:gcsio:2.2.16=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud.bigdataoss:util:2.2.16=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud.bigtable:bigtable-client-core-config:1.28.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud.datastore:datastore-v1-proto-client:2.16.3=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud.sql:jdbc-socket-factory-core:1.14.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud.sql:postgres-socket-factory:1.14.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-bigquerystorage:2.41.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-bigtable-stats:2.26.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-bigtable:2.26.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-core-grpc:2.22.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-core-http:2.21.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-core:2.22.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-firestore:3.14.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-monitoring:1.82.0=compileClasspath,testCompileClasspath
|
||||
com.google.cloud:google-cloud-monitoring:3.24.0=runtimeClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-pubsub:1.124.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-pubsublite:1.12.13=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-secretmanager:2.23.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-spanner:6.45.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-storage:2.22.6=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:google-cloud-tasks:2.23.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:grpc-gcp:1.4.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.cloud:proto-google-cloud-firestore-bundle-v1:3.14.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.code.findbugs:jsr305:3.0.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.code.gson:gson:2.10.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.common.html.types:types:1.0.6=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.dagger:dagger:2.48=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.errorprone:error_prone_annotations:2.21.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.escapevelocity:escapevelocity:0.9.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.flatbuffers:flatbuffers-java:1.12.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.flogger:flogger-system-backend:0.7.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.flogger:flogger:0.7.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.flogger:google-extensions:0.7.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.guava:failureaccess:1.0.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.guava:guava-parent:32.1.2-jre=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.guava:guava:32.1.2-jre=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.gwt:gwt-user:2.10.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.http-client:google-http-client-apache-v2:1.43.3=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.http-client:google-http-client-appengine:1.43.3=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.http-client:google-http-client-gson:1.43.3=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.http-client:google-http-client-jackson2:1.43.3=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.http-client:google-http-client-protobuf:1.43.3=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.http-client:google-http-client:1.43.3=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.inject.extensions:guice-multibindings:4.1.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.inject:guice:4.1.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.j2objc:j2objc-annotations:2.8=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.jsinterop:jsinterop-annotations:2.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.monitoring-client:metrics:1.0.7=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.monitoring-client:stackdriver:1.0.7=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.oauth-client:google-oauth-client-appengine:1.34.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.oauth-client:google-oauth-client-java6:1.34.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.oauth-client:google-oauth-client-jetty:1.34.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.oauth-client:google-oauth-client-servlet:1.34.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.oauth-client:google-oauth-client:1.34.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.protobuf:protobuf-java-util:3.23.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.protobuf:protobuf-java:3.23.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.re2j:re2j:1.7=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.template:soy:2021-02-01=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.google.truth:truth:1.1.5=runtimeClasspath,testRuntimeClasspath
|
||||
com.googlecode.json-simple:json-simple:1.1.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.ibm.icu:icu4j:57.1=compileClasspath,testCompileClasspath
|
||||
com.ibm.icu:icu4j:73.2=runtimeClasspath,testRuntimeClasspath
|
||||
com.jcraft:jsch:0.1.55=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.lmax:disruptor:3.4.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.sun.istack:istack-commons-runtime:3.0.7=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.sun.xml.fastinfoset:FastInfoset:1.2.15=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.thoughtworks.paranamer:paranamer:2.7=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.zaxxer:HikariCP:3.4.5=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
commons-codec:commons-codec:1.15=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
commons-logging:commons-logging:1.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
dnsjava:dnsjava:3.5.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.confluent:common-config:5.3.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.confluent:common-utils:5.3.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.confluent:kafka-avro-serializer:5.3.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.confluent:kafka-schema-registry-client:5.3.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.github.classgraph:classgraph:4.8.104=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.github.java-diff-utils:java-diff-utils:4.12=runtimeClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-alts:1.56.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-api:1.56.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-auth:1.56.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-census:1.56.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-context:1.56.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-core:1.56.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-googleapis:1.56.1=runtimeClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-grpclb:1.56.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-netty-shaded:1.56.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-netty:1.56.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-protobuf-lite:1.56.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-protobuf:1.56.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-rls:1.56.1=runtimeClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-services:1.56.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-stub:1.56.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.grpc:grpc-xds:1.56.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.netty:netty-buffer:4.1.87.Final=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.netty:netty-codec-http2:4.1.87.Final=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.netty:netty-codec-http:4.1.87.Final=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.netty:netty-codec-socks:4.1.87.Final=runtimeClasspath,testRuntimeClasspath
|
||||
io.netty:netty-codec:4.1.87.Final=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.netty:netty-common:4.1.87.Final=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.netty:netty-handler-proxy:4.1.87.Final=runtimeClasspath,testRuntimeClasspath
|
||||
io.netty:netty-handler:4.1.87.Final=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.netty:netty-resolver:4.1.87.Final=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.netty:netty-tcnative-boringssl-static:2.0.52.Final=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.netty:netty-tcnative-classes:2.0.52.Final=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.netty:netty-transport-native-unix-common:4.1.87.Final=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.netty:netty-transport:4.1.87.Final=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.opencensus:opencensus-api:0.31.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.opencensus:opencensus-contrib-exemplar-util:0.31.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.opencensus:opencensus-contrib-grpc-metrics:0.31.0=compileClasspath,testCompileClasspath
|
||||
io.opencensus:opencensus-contrib-grpc-metrics:0.31.1=runtimeClasspath,testRuntimeClasspath
|
||||
io.opencensus:opencensus-contrib-grpc-util:0.31.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.opencensus:opencensus-contrib-http-util:0.31.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.opencensus:opencensus-contrib-resource-util:0.31.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.opencensus:opencensus-exporter-metrics-util:0.31.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.opencensus:opencensus-exporter-stats-stackdriver:0.31.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.opencensus:opencensus-impl-core:0.31.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.opencensus:opencensus-impl:0.31.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.opencensus:opencensus-proto:0.2.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.perfmark:perfmark-api:0.26.0=runtimeClasspath,testRuntimeClasspath
|
||||
javax.activation:activation:1.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
javax.activation:javax.activation-api:1.2.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
javax.annotation:javax.annotation-api:1.3.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
javax.annotation:jsr250-api:1.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
javax.inject:javax.inject:1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
javax.jdo:jdo2-api:2.3-20090302111651=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
javax.mail:mail:1.5.0-b01=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
javax.persistence:javax.persistence-api:2.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
javax.servlet:servlet-api:2.5=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
javax.validation:validation-api:1.0.0.GA=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
javax.xml.bind:jaxb-api:2.3.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
jline:jline:1.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
joda-time:joda-time:2.10.14=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
net.bytebuddy:byte-buddy:1.12.18=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
net.java.dev.jna:jna:5.12.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.arrow:arrow-format:5.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.arrow:arrow-memory-core:5.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.arrow:arrow-vector:5.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.avro:avro:1.8.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-model-fn-execution:2.50.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-model-job-management:2.50.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-model-pipeline:2.50.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-runners-core-construction-java:2.50.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-runners-core-java:2.50.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-runners-google-cloud-dataflow-java:2.50.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-runners-java-fn-execution:2.50.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-core:2.50.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-expansion-service:2.50.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-extensions-arrow:2.50.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-extensions-avro:2.50.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core:2.50.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-extensions-protobuf:2.50.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-fn-execution:2.50.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-harness:2.50.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-io-google-cloud-platform:2.50.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-sdks-java-io-kafka:2.50.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-vendor-grpc-1_54_0:0.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.beam:beam-vendor-guava-32_1_2-jre:0.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.commons:commons-compress:1.23.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.commons:commons-csv:1.10.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.commons:commons-lang3:3.13.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.httpcomponents:httpclient:4.5.14=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.apache.httpcomponents:httpcore:4.4.16=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.bouncycastle:bcpg-jdk15on:1.67=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.bouncycastle:bcpkix-jdk15on:1.67=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.bouncycastle:bcprov-jdk15on:1.67=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.checkerframework:checker-compat-qual:2.5.3=compileClasspath,testCompileClasspath
|
||||
org.checkerframework:checker-compat-qual:2.5.5=runtimeClasspath,testRuntimeClasspath
|
||||
org.checkerframework:checker-qual:3.33.0=compileClasspath,testCompileClasspath
|
||||
org.checkerframework:checker-qual:3.35.0=runtimeClasspath,testRuntimeClasspath
|
||||
org.codehaus.jackson:jackson-core-asl:1.9.13=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.codehaus.jackson:jackson-mapper-asl:1.9.13=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.codehaus.mojo:animal-sniffer-annotations:1.23=runtimeClasspath,testRuntimeClasspath
|
||||
org.conscrypt:conscrypt-openjdk-uber:2.5.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-http:9.4.49.v20220914=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-io:9.4.49.v20220914=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-security:9.4.49.v20220914=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-server:9.4.49.v20220914=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-servlet:9.4.49.v20220914=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-util-ajax:9.4.49.v20220914=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-util:9.4.49.v20220914=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.flywaydb:flyway-core:9.22.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.glassfish.jaxb:jaxb-runtime:2.3.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.glassfish.jaxb:txw2:2.3.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.gwtproject:gwt-user:2.10.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.hamcrest:hamcrest:2.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.hibernate.common:hibernate-commons-annotations:5.1.2.Final=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.hibernate:hibernate-core:5.6.15.Final=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.hibernate:hibernate-hikaricp:5.6.15.Final=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.jboss.logging:jboss-logging:3.4.3.Final=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.jboss.spec.javax.transaction:jboss-transaction-api_1.2_spec:1.1.1.Final=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.jboss:jandex:2.4.2.Final=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.jetbrains:annotations:17.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.joda:joda-money:1.0.3=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.json:json:20230618=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.jsoup:jsoup:1.16.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.jvnet.staxex:stax-ex:1.8=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.ow2.asm:asm-analysis:9.5=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.ow2.asm:asm-commons:9.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.ow2.asm:asm-tree:9.5=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.ow2.asm:asm-util:9.5=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.ow2.asm:asm:9.5=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.postgresql:postgresql:42.6.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.rnorth.duct-tape:duct-tape:1.0.8=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.slf4j:slf4j-api:2.0.9=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.slf4j:slf4j-jdk14:2.0.9=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.springframework:spring-core:5.3.27=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.springframework:spring-expression:5.3.27=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.springframework:spring-jcl:5.3.27=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.testcontainers:database-commons:1.19.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.testcontainers:jdbc:1.19.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.testcontainers:postgresql:1.19.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.testcontainers:testcontainers:1.19.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.threeten:threetenbp:1.6.8=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.tukaani:xz:1.5=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.w3c.css:sac:1.3=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.xerial.snappy:snappy-java:1.1.10.3=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.yaml:snakeyaml:2.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
us.fatehi:schemacrawler-api:16.10.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
us.fatehi:schemacrawler-diagram:16.10.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
us.fatehi:schemacrawler-tools:16.10.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
us.fatehi:schemacrawler-utility:16.10.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
us.fatehi:schemacrawler:16.10.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
xerces:xmlParserAPIs:2.6.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
xpp3:xpp3:1.1.4c=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
empty=annotationProcessor,providedCompile,providedRuntime,testAnnotationProcessor
|
||||
@@ -19,30 +19,25 @@ import com.google.common.net.HttpHeaders;
|
||||
/** Utility class of HTTP header names used for HTTP calls between Nomulus and the proxy. */
|
||||
public final class ProxyHttpHeaders {
|
||||
|
||||
/**
|
||||
* HTTP header name used to pass a full SSL certificate from the proxy to Nomulus.
|
||||
*
|
||||
* <p>This header contains the SSL certificate encoded to a string. It is used to pass the client
|
||||
* certificate used for login to Nomulus for validation.
|
||||
*/
|
||||
public static final String FULL_CERTIFICATE = "X-SSL-Full-Certificate";
|
||||
|
||||
/** HTTP header name used to pass the certificate hash from the proxy to Nomulus. */
|
||||
public static final String CERTIFICATE_HASH = "X-SSL-Certificate";
|
||||
|
||||
/**
|
||||
* HTTP header name passed from Nomulus to proxy to indicate that a client has successfully logged
|
||||
* in.
|
||||
*/
|
||||
public static final String LOGGED_IN = "Logged-In";
|
||||
|
||||
/**
|
||||
* HTTP header name passed from Nomulus to proxy to indicate that an EPP session should be closed.
|
||||
*/
|
||||
public static final String EPP_SESSION = "Epp-Session";
|
||||
|
||||
/** HTTP header name used to pass the client IP address from the proxy to Nomulus. */
|
||||
public static final String IP_ADDRESS = HttpHeaders.X_FORWARDED_FOR;
|
||||
public static final String IP_ADDRESS = "Nomulus-Client-Address";
|
||||
|
||||
/**
|
||||
* Fallback HTTP header name used to pass the client IP address from the proxy to Nomulus.
|
||||
*
|
||||
* <p>Note that Java 17's servlet implementation (at least on App Engine) injects some seemingly
|
||||
* unrelated addresses into this header. We only use this as a fallback so the proxy can
|
||||
* transition to use the above header that should not be interfered with.
|
||||
*/
|
||||
public static final String FALLBACK_IP_ADDRESS = HttpHeaders.X_FORWARDED_FOR;
|
||||
|
||||
private ProxyHttpHeaders() {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user