diff --git a/core/src/main/java/google/registry/beam/invoicing/InvoicingPipeline.java b/core/src/main/java/google/registry/beam/invoicing/InvoicingPipeline.java index 71c170981..6f4d4aff2 100644 --- a/core/src/main/java/google/registry/beam/invoicing/InvoicingPipeline.java +++ b/core/src/main/java/google/registry/beam/invoicing/InvoicingPipeline.java @@ -14,13 +14,13 @@ package google.registry.beam.invoicing; -import com.google.auth.oauth2.GoogleCredentials; import google.registry.beam.invoicing.BillingEvent.InvoiceGroupingKey; import google.registry.beam.invoicing.BillingEvent.InvoiceGroupingKey.InvoiceGroupingKeyCoder; +import google.registry.config.CredentialModule.LocalCredential; import google.registry.config.RegistryConfig.Config; import google.registry.reporting.billing.BillingModule; import google.registry.reporting.billing.GenerateInvoicesAction; -import google.registry.tools.AuthModule.LocalOAuth2Credentials; +import google.registry.util.GoogleCredentialsBundle; import java.io.Serializable; import javax.inject.Inject; import org.apache.beam.runners.dataflow.DataflowRunner; @@ -81,8 +81,8 @@ public class InvoicingPipeline implements Serializable { @Config("invoiceFilePrefix") String invoiceFilePrefix; - @Inject @LocalOAuth2Credentials - GoogleCredentials credentials; + @Inject @LocalCredential + GoogleCredentialsBundle credentialsBundle; @Inject InvoicingPipeline() {} @@ -105,7 +105,7 @@ public class InvoicingPipeline implements Serializable { public void deploy() { // We can't store options as a member variable due to serialization concerns. InvoicingPipelineOptions options = PipelineOptionsFactory.as(InvoicingPipelineOptions.class); - options.setGcpCredential(credentials); + options.setGcpCredential(credentialsBundle.getGoogleCredentials()); options.setProject(projectId); options.setRunner(DataflowRunner.class); // This causes p.run() to stage the pipeline as a template on GCS, as opposed to running it. diff --git a/core/src/main/java/google/registry/bigquery/BigqueryModule.java b/core/src/main/java/google/registry/bigquery/BigqueryModule.java index 197854ed1..fd3283d0a 100644 --- a/core/src/main/java/google/registry/bigquery/BigqueryModule.java +++ b/core/src/main/java/google/registry/bigquery/BigqueryModule.java @@ -14,7 +14,6 @@ package google.registry.bigquery; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.services.bigquery.Bigquery; import com.google.api.services.bigquery.model.TableFieldSchema; import com.google.common.collect.ImmutableList; @@ -23,24 +22,29 @@ import dagger.Provides; import dagger.multibindings.Multibinds; import google.registry.config.CredentialModule.DefaultCredential; import google.registry.config.RegistryConfig.Config; +import google.registry.util.GoogleCredentialsBundle; import java.util.Map; /** Dagger module for Google {@link Bigquery} connection objects. */ @Module public abstract class BigqueryModule { - /** Provides a map of BigQuery table names to field names. */ - @Multibinds - abstract Map> bigquerySchemas(); + // No subclasses. + private BigqueryModule() {} @Provides static Bigquery provideBigquery( - @DefaultCredential GoogleCredential credential, @Config("projectId") String projectId) { - return new Bigquery.Builder(credential.getTransport(), credential.getJsonFactory(), credential) + @DefaultCredential GoogleCredentialsBundle credentialsBundle, + @Config("projectId") String projectId) { + return new Bigquery.Builder( + credentialsBundle.getHttpTransport(), + credentialsBundle.getJsonFactory(), + credentialsBundle.getHttpRequestInitializer()) .setApplicationName(projectId) .build(); } - // No subclasses. - private BigqueryModule() {} + /** Provides a map of BigQuery table names to field names. */ + @Multibinds + abstract Map> bigquerySchemas(); } diff --git a/core/src/main/java/google/registry/config/CredentialModule.java b/core/src/main/java/google/registry/config/CredentialModule.java index fba114fa4..f57f70564 100644 --- a/core/src/main/java/google/registry/config/CredentialModule.java +++ b/core/src/main/java/google/registry/config/CredentialModule.java @@ -16,32 +16,28 @@ package google.registry.config; import static java.nio.charset.StandardCharsets.UTF_8; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; -import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; -import com.google.api.client.googleapis.util.Utils; +import com.google.auth.oauth2.GoogleCredentials; import com.google.common.collect.ImmutableList; import dagger.Module; import dagger.Provides; import google.registry.config.RegistryConfig.Config; import google.registry.keyring.api.KeyModule.Key; +import google.registry.util.GoogleCredentialsBundle; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.UncheckedIOException; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.security.GeneralSecurityException; import javax.inject.Qualifier; import javax.inject.Singleton; -/** - * Dagger module that provides all {@link GoogleCredential GoogleCredentials} used in the - * application. - */ +/** Dagger module that provides all {@link GoogleCredentials} used in the application. */ @Module public abstract class CredentialModule { /** - * Provides the default {@link GoogleCredential} from the Google Cloud runtime. + * Provides the default {@link GoogleCredentialsBundle} from the Google Cloud runtime. * *

The credential returned depends on the runtime environment: * @@ -58,22 +54,22 @@ public abstract class CredentialModule { @DefaultCredential @Provides @Singleton - public static GoogleCredential provideDefaultCredential( + public static GoogleCredentialsBundle provideDefaultCredential( @Config("defaultCredentialOauthScopes") ImmutableList requiredScopes) { - GoogleCredential credential; + GoogleCredentials credential; try { - credential = GoogleCredential.getApplicationDefault(); + credential = GoogleCredentials.getApplicationDefault(); } catch (IOException e) { throw new RuntimeException(e); } if (credential.createScopedRequired()) { - return credential.createScoped(requiredScopes); + credential = credential.createScoped(requiredScopes); } - return credential; + return GoogleCredentialsBundle.create(credential); } /** - * Provides a {@link GoogleCredential} from the service account's JSON key file. + * Provides a {@link GoogleCredentialsBundle} from the service account's JSON key file. * *

On App Engine, a thread created using Java's built-in API needs this credential when it * calls App Engine API. The Google Sheets API also needs this credential. @@ -81,28 +77,24 @@ public abstract class CredentialModule { @JsonCredential @Provides @Singleton - public static GoogleCredential provideJsonCredential( + public static GoogleCredentialsBundle provideJsonCredential( @Config("defaultCredentialOauthScopes") ImmutableList requiredScopes, @Key("jsonCredential") String jsonCredential) { - GoogleCredential credential; + GoogleCredentials credential; try { credential = - GoogleCredential.fromStream( - new ByteArrayInputStream(jsonCredential.getBytes(UTF_8)), - // We cannot use UrlFetchTransport as that uses App Engine API. - GoogleNetHttpTransport.newTrustedTransport(), - Utils.getDefaultJsonFactory()); - } catch (IOException | GeneralSecurityException e) { - throw new RuntimeException(e); + GoogleCredentials.fromStream(new ByteArrayInputStream(jsonCredential.getBytes(UTF_8))); + } catch (IOException e) { + throw new UncheckedIOException(e); } if (credential.createScopedRequired()) { credential = credential.createScoped(requiredScopes); } - return credential; + return GoogleCredentialsBundle.create(credential); } /** - * Provides a {@link GoogleCredential} with delegated admin access for a G Suite domain. + * Provides a {@link GoogleCredentialsBundle} with delegated admin access for a G Suite domain. * *

The G Suite domain must grant delegated admin access to the registry service account with * all scopes in {@code requiredScopes}, including ones not related to G Suite. @@ -110,18 +102,14 @@ public abstract class CredentialModule { @DelegatedCredential @Provides @Singleton - public static GoogleCredential provideDelegatedCredential( + public static GoogleCredentialsBundle provideDelegatedCredential( @Config("delegatedCredentialOauthScopes") ImmutableList requiredScopes, - @JsonCredential GoogleCredential googleCredential, + @JsonCredential GoogleCredentialsBundle credentialsBundle, @Config("gSuiteAdminAccountEmailAddress") String gSuiteAdminAccountEmailAddress) { - return new GoogleCredential.Builder() - .setTransport(Utils.getDefaultTransport()) - .setJsonFactory(Utils.getDefaultJsonFactory()) - .setServiceAccountId(googleCredential.getServiceAccountId()) - .setServiceAccountPrivateKey(googleCredential.getServiceAccountPrivateKey()) - .setServiceAccountScopes(requiredScopes) - .setServiceAccountUser(gSuiteAdminAccountEmailAddress) - .build(); + return GoogleCredentialsBundle.create(credentialsBundle + .getGoogleCredentials() + .createDelegated(gSuiteAdminAccountEmailAddress) + .createScoped(requiredScopes)); } /** Dagger qualifier for the Application Default Credential. */ diff --git a/core/src/main/java/google/registry/dns/writer/clouddns/CloudDnsWriterModule.java b/core/src/main/java/google/registry/dns/writer/clouddns/CloudDnsWriterModule.java index f43d9f822..32ee16c7d 100644 --- a/core/src/main/java/google/registry/dns/writer/clouddns/CloudDnsWriterModule.java +++ b/core/src/main/java/google/registry/dns/writer/clouddns/CloudDnsWriterModule.java @@ -14,7 +14,6 @@ package google.registry.dns.writer.clouddns; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.services.dns.Dns; import com.google.common.util.concurrent.RateLimiter; import dagger.Binds; @@ -26,6 +25,7 @@ import dagger.multibindings.StringKey; import google.registry.config.CredentialModule.DefaultCredential; import google.registry.config.RegistryConfig.Config; import google.registry.dns.writer.DnsWriter; +import google.registry.util.GoogleCredentialsBundle; import java.util.Optional; import javax.inject.Named; @@ -35,12 +35,15 @@ public abstract class CloudDnsWriterModule { @Provides static Dns provideDns( - @DefaultCredential GoogleCredential credential, + @DefaultCredential GoogleCredentialsBundle credentialsBundle, @Config("projectId") String projectId, @Config("cloudDnsRootUrl") Optional rootUrl, @Config("cloudDnsServicePath") Optional servicePath) { Dns.Builder builder = - new Dns.Builder(credential.getTransport(), credential.getJsonFactory(), credential) + new Dns.Builder( + credentialsBundle.getHttpTransport(), + credentialsBundle.getJsonFactory(), + credentialsBundle.getHttpRequestInitializer()) .setApplicationName(projectId); rootUrl.ifPresent(builder::setRootUrl); diff --git a/core/src/main/java/google/registry/export/DriveModule.java b/core/src/main/java/google/registry/export/DriveModule.java index 984cbda0f..a0500fd15 100644 --- a/core/src/main/java/google/registry/export/DriveModule.java +++ b/core/src/main/java/google/registry/export/DriveModule.java @@ -14,7 +14,6 @@ package google.registry.export; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.services.drive.Drive; import dagger.Component; import dagger.Module; @@ -24,6 +23,7 @@ import google.registry.config.CredentialModule.DefaultCredential; import google.registry.config.RegistryConfig.Config; import google.registry.config.RegistryConfig.ConfigModule; import google.registry.storage.drive.DriveConnection; +import google.registry.util.GoogleCredentialsBundle; import javax.inject.Singleton; /** Dagger module for Google {@link Drive} service connection objects. */ @@ -32,8 +32,13 @@ public final class DriveModule { @Provides static Drive provideDrive( - @DefaultCredential GoogleCredential credential, @Config("projectId") String projectId) { - return new Drive.Builder(credential.getTransport(), credential.getJsonFactory(), credential) + @DefaultCredential GoogleCredentialsBundle credentialsBundle, + @Config("projectId") String projectId) { + + return new Drive.Builder( + credentialsBundle.getHttpTransport(), + credentialsBundle.getJsonFactory(), + credentialsBundle.getHttpRequestInitializer()) .setApplicationName(projectId) .build(); } diff --git a/core/src/main/java/google/registry/export/datastore/DatastoreAdminModule.java b/core/src/main/java/google/registry/export/datastore/DatastoreAdminModule.java index 322fb0e2f..b104beec9 100644 --- a/core/src/main/java/google/registry/export/datastore/DatastoreAdminModule.java +++ b/core/src/main/java/google/registry/export/datastore/DatastoreAdminModule.java @@ -14,11 +14,11 @@ package google.registry.export.datastore; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import dagger.Module; import dagger.Provides; import google.registry.config.CredentialModule; import google.registry.config.RegistryConfig; +import google.registry.util.GoogleCredentialsBundle; import javax.inject.Singleton; /** Dagger module that configures provision of {@link DatastoreAdmin}. */ @@ -28,10 +28,12 @@ public abstract class DatastoreAdminModule { @Singleton @Provides static DatastoreAdmin provideDatastoreAdmin( - @CredentialModule.DefaultCredential GoogleCredential credential, + @CredentialModule.DefaultCredential GoogleCredentialsBundle credentialsBundle, @RegistryConfig.Config("projectId") String projectId) { return new DatastoreAdmin.Builder( - credential.getTransport(), credential.getJsonFactory(), credential) + credentialsBundle.getHttpTransport(), + credentialsBundle.getJsonFactory(), + credentialsBundle.getHttpRequestInitializer()) .setApplicationName(projectId) .setProjectId(projectId) .build(); diff --git a/core/src/main/java/google/registry/export/sheet/SheetsServiceModule.java b/core/src/main/java/google/registry/export/sheet/SheetsServiceModule.java index 2640614b6..33a0201bc 100644 --- a/core/src/main/java/google/registry/export/sheet/SheetsServiceModule.java +++ b/core/src/main/java/google/registry/export/sheet/SheetsServiceModule.java @@ -14,12 +14,12 @@ package google.registry.export.sheet; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.services.sheets.v4.Sheets; import dagger.Module; import dagger.Provides; import google.registry.config.CredentialModule.JsonCredential; import google.registry.config.RegistryConfig.Config; +import google.registry.util.GoogleCredentialsBundle; /** Dagger module for {@link Sheets}. */ @Module @@ -27,8 +27,12 @@ public final class SheetsServiceModule { @Provides static Sheets provideSheets( - @JsonCredential GoogleCredential credential, @Config("projectId") String projectId) { - return new Sheets.Builder(credential.getTransport(), credential.getJsonFactory(), credential) + @JsonCredential GoogleCredentialsBundle credentialsBundle, + @Config("projectId") String projectId) { + return new Sheets.Builder( + credentialsBundle.getHttpTransport(), + credentialsBundle.getJsonFactory(), + credentialsBundle.getHttpRequestInitializer()) .setApplicationName(projectId) .build(); } diff --git a/core/src/main/java/google/registry/groups/DirectoryModule.java b/core/src/main/java/google/registry/groups/DirectoryModule.java index e5fe05f6c..f31311ddf 100644 --- a/core/src/main/java/google/registry/groups/DirectoryModule.java +++ b/core/src/main/java/google/registry/groups/DirectoryModule.java @@ -14,12 +14,12 @@ package google.registry.groups; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.services.admin.directory.Directory; import dagger.Module; import dagger.Provides; import google.registry.config.CredentialModule.DelegatedCredential; import google.registry.config.RegistryConfig.Config; +import google.registry.util.GoogleCredentialsBundle; /** Dagger module for the Google {@link Directory} service. */ @Module @@ -27,8 +27,12 @@ public final class DirectoryModule { @Provides static Directory provideDirectory( - @DelegatedCredential GoogleCredential credential, @Config("projectId") String projectId) { - return new Directory.Builder(credential.getTransport(), credential.getJsonFactory(), credential) + @DelegatedCredential GoogleCredentialsBundle credentialsBundle, + @Config("projectId") String projectId) { + return new Directory.Builder( + credentialsBundle.getHttpTransport(), + credentialsBundle.getJsonFactory(), + credentialsBundle.getHttpRequestInitializer()) .setApplicationName(projectId) .build(); } diff --git a/core/src/main/java/google/registry/groups/GroupssettingsModule.java b/core/src/main/java/google/registry/groups/GroupssettingsModule.java index 23621e58c..e5a437073 100644 --- a/core/src/main/java/google/registry/groups/GroupssettingsModule.java +++ b/core/src/main/java/google/registry/groups/GroupssettingsModule.java @@ -14,12 +14,12 @@ package google.registry.groups; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.services.groupssettings.Groupssettings; import dagger.Module; import dagger.Provides; import google.registry.config.CredentialModule.DelegatedCredential; import google.registry.config.RegistryConfig.Config; +import google.registry.util.GoogleCredentialsBundle; /** Dagger module for the Google {@link Groupssettings} service. */ @Module @@ -27,9 +27,12 @@ public final class GroupssettingsModule { @Provides static Groupssettings provideDirectory( - @DelegatedCredential GoogleCredential credential, @Config("projectId") String projectId) { + @DelegatedCredential GoogleCredentialsBundle credentialsBundle, + @Config("projectId") String projectId) { return new Groupssettings.Builder( - credential.getTransport(), credential.getJsonFactory(), credential) + credentialsBundle.getHttpTransport(), + credentialsBundle.getJsonFactory(), + credentialsBundle.getHttpRequestInitializer()) .setApplicationName(projectId) .build(); } diff --git a/core/src/main/java/google/registry/keyring/kms/KmsModule.java b/core/src/main/java/google/registry/keyring/kms/KmsModule.java index 1c96ca50e..a1b57b92f 100644 --- a/core/src/main/java/google/registry/keyring/kms/KmsModule.java +++ b/core/src/main/java/google/registry/keyring/kms/KmsModule.java @@ -14,7 +14,6 @@ package google.registry.keyring.kms; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.services.cloudkms.v1.CloudKMS; import dagger.Binds; import dagger.Module; @@ -24,6 +23,7 @@ import dagger.multibindings.StringKey; import google.registry.config.CredentialModule.DefaultCredential; import google.registry.config.RegistryConfig.Config; import google.registry.keyring.api.Keyring; +import google.registry.util.GoogleCredentialsBundle; /** Dagger module for Cloud KMS. */ @Module @@ -31,20 +31,23 @@ public abstract class KmsModule { public static final String NAME = "KMS"; - @Binds - @IntoMap - @StringKey(NAME) - abstract Keyring provideKeyring(KmsKeyring keyring); - @Provides static CloudKMS provideKms( - @DefaultCredential GoogleCredential credential, + @DefaultCredential GoogleCredentialsBundle credentialsBundle, @Config("cloudKmsProjectId") String projectId) { - return new CloudKMS.Builder(credential.getTransport(), credential.getJsonFactory(), credential) + return new CloudKMS.Builder( + credentialsBundle.getHttpTransport(), + credentialsBundle.getJsonFactory(), + credentialsBundle.getHttpRequestInitializer()) .setApplicationName(projectId) .build(); } + @Binds + @IntoMap + @StringKey(NAME) + abstract Keyring provideKeyring(KmsKeyring keyring); + @Binds abstract KmsConnection provideKmsConnection(KmsConnectionImpl kmsConnectionImpl); } diff --git a/core/src/main/java/google/registry/monitoring/whitebox/StackdriverModule.java b/core/src/main/java/google/registry/monitoring/whitebox/StackdriverModule.java index a5d0427ea..d0ad4ad22 100644 --- a/core/src/main/java/google/registry/monitoring/whitebox/StackdriverModule.java +++ b/core/src/main/java/google/registry/monitoring/whitebox/StackdriverModule.java @@ -14,7 +14,6 @@ package google.registry.monitoring.whitebox; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.services.monitoring.v3.Monitoring; import com.google.api.services.monitoring.v3.model.MonitoredResource; import com.google.appengine.api.modules.ModulesService; @@ -27,6 +26,7 @@ import dagger.Module; import dagger.Provides; import google.registry.config.CredentialModule.JsonCredential; import google.registry.config.RegistryConfig.Config; +import google.registry.util.GoogleCredentialsBundle; import org.joda.time.Duration; /** Dagger module for Google Stackdriver service connection objects. */ @@ -39,9 +39,12 @@ public final class StackdriverModule { @Provides static Monitoring provideMonitoring( - @JsonCredential GoogleCredential credential, @Config("projectId") String projectId) { + @JsonCredential GoogleCredentialsBundle credentialsBundle, + @Config("projectId") String projectId) { return new Monitoring.Builder( - credential.getTransport(), credential.getJsonFactory(), credential) + credentialsBundle.getHttpTransport(), + credentialsBundle.getJsonFactory(), + credentialsBundle.getHttpRequestInitializer()) .setApplicationName(projectId) .build(); } diff --git a/core/src/main/java/google/registry/reporting/ReportingModule.java b/core/src/main/java/google/registry/reporting/ReportingModule.java index 2ffe40bd9..3da2e47ea 100644 --- a/core/src/main/java/google/registry/reporting/ReportingModule.java +++ b/core/src/main/java/google/registry/reporting/ReportingModule.java @@ -17,7 +17,6 @@ package google.registry.reporting; import static google.registry.request.RequestParameters.extractOptionalParameter; import static google.registry.request.RequestParameters.extractRequiredParameter; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.services.dataflow.Dataflow; import dagger.Module; import dagger.Provides; @@ -25,6 +24,7 @@ import google.registry.config.CredentialModule.DefaultCredential; import google.registry.config.RegistryConfig.Config; import google.registry.request.HttpException.BadRequestException; import google.registry.request.Parameter; +import google.registry.util.GoogleCredentialsBundle; import google.registry.util.Clock; import java.util.Optional; import javax.servlet.http.HttpServletRequest; @@ -118,8 +118,12 @@ public class ReportingModule { /** Constructs a {@link Dataflow} API client with default settings. */ @Provides static Dataflow provideDataflow( - @DefaultCredential GoogleCredential credential, @Config("projectId") String projectId) { - return new Dataflow.Builder(credential.getTransport(), credential.getJsonFactory(), credential) + @DefaultCredential GoogleCredentialsBundle credentialsBundle, + @Config("projectId") String projectId) { + return new Dataflow.Builder( + credentialsBundle.getHttpTransport(), + credentialsBundle.getJsonFactory(), + credentialsBundle.getHttpRequestInitializer()) .setApplicationName(String.format("%s billing", projectId)) .build(); } diff --git a/core/src/main/java/google/registry/tools/AppEngineAdminApiModule.java b/core/src/main/java/google/registry/tools/AppEngineAdminApiModule.java index dedbf4142..71f08f132 100644 --- a/core/src/main/java/google/registry/tools/AppEngineAdminApiModule.java +++ b/core/src/main/java/google/registry/tools/AppEngineAdminApiModule.java @@ -14,13 +14,12 @@ package google.registry.tools; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; -import com.google.api.client.googleapis.util.Utils; import com.google.api.services.appengine.v1.Appengine; import dagger.Module; import dagger.Provides; import google.registry.config.CredentialModule.LocalCredential; import google.registry.config.RegistryConfig.Config; +import google.registry.util.GoogleCredentialsBundle; import javax.inject.Singleton; /** Module providing the instance of {@link Appengine} to access App Engine Admin Api. */ @@ -30,9 +29,12 @@ public abstract class AppEngineAdminApiModule { @Provides @Singleton public static Appengine provideAppengine( - @LocalCredential GoogleCredential credential, @Config("projectId") String projectId) { + @LocalCredential GoogleCredentialsBundle credentialsBundle, + @Config("projectId") String projectId) { return new Appengine.Builder( - Utils.getDefaultTransport(), Utils.getDefaultJsonFactory(), credential) + credentialsBundle.getHttpTransport(), + credentialsBundle.getJsonFactory(), + credentialsBundle.getHttpRequestInitializer()) .setApplicationName(projectId) .build(); } diff --git a/core/src/main/java/google/registry/tools/AuthModule.java b/core/src/main/java/google/registry/tools/AuthModule.java index 8dbbbdba7..28228b695 100644 --- a/core/src/main/java/google/registry/tools/AuthModule.java +++ b/core/src/main/java/google/registry/tools/AuthModule.java @@ -20,7 +20,6 @@ import com.google.api.client.auth.oauth2.Credential; import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow; import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets; import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets.Details; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.JsonFactory; import com.google.api.client.util.store.AbstractDataStoreFactory; @@ -39,10 +38,10 @@ import google.registry.config.CredentialModule.DefaultCredential; import google.registry.config.CredentialModule.LocalCredential; import google.registry.config.CredentialModule.LocalCredentialJson; import google.registry.config.RegistryConfig.Config; +import google.registry.util.GoogleCredentialsBundle; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; -import java.io.UncheckedIOException; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -60,14 +59,6 @@ public class AuthModule { private static final File DATA_STORE_DIR = new File(System.getProperty("user.home"), ".config/nomulus/credentials"); - @Module - abstract static class LocalCredentialModule { - @Binds - @DefaultCredential - abstract GoogleCredential provideLocalCredentialAsDefaultCredential( - @LocalCredential GoogleCredential credential); - } - @Provides @StoredCredential static Credential provideCredential( @@ -86,38 +77,21 @@ public class AuthModule { @Provides @LocalCredential - public static GoogleCredential provideLocalCredential( + public static GoogleCredentialsBundle provideLocalCredential( @LocalCredentialJson String credentialJson, @Config("localCredentialOauthScopes") ImmutableList scopes) { try { - GoogleCredential credential = - GoogleCredential.fromStream(new ByteArrayInputStream(credentialJson.getBytes(UTF_8))); + GoogleCredentials credential = + GoogleCredentials.fromStream(new ByteArrayInputStream(credentialJson.getBytes(UTF_8))); if (credential.createScopedRequired()) { credential = credential.createScoped(scopes); } - return credential; + return GoogleCredentialsBundle.create(credential); } catch (IOException e) { throw new RuntimeException(e); } } - @Provides - @LocalOAuth2Credentials - public static GoogleCredentials provideLocalOAuth2Credentials( - @LocalCredentialJson String credentialJson, - @Config("localCredentialOauthScopes") ImmutableList scopes) { - try { - GoogleCredentials credentials = - GoogleCredentials.fromStream(new ByteArrayInputStream(credentialJson.getBytes(UTF_8))); - if (credentials.createScopedRequired()) { - credentials = credentials.createScoped(scopes); - } - return credentials; - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - @Provides public static GoogleAuthorizationCodeFlow provideAuthorizationCodeFlow( JsonFactory jsonFactory, @@ -198,16 +172,11 @@ public class AuthModule { } } - /** Raised when we need a user login. */ - static class LoginRequiredException extends RuntimeException { - LoginRequiredException() {} - } - /** * Dagger qualifier for the {@link Credential} constructed from the data stored on disk. * *

This {@link Credential} should not be used in another module, hence the private qualifier. - * It's only use is to build a {@link GoogleCredential}, which is used in injection sites + * It's only use is to build a {@link GoogleCredentials}, which is used in injection sites * elsewhere. */ @Qualifier @@ -227,9 +196,16 @@ public class AuthModule { @Retention(RetentionPolicy.RUNTIME) @interface OAuthClientId {} - /** Dagger qualifier for the local OAuth2 Credentials. */ - @Qualifier - @Documented - @Retention(RetentionPolicy.RUNTIME) - public @interface LocalOAuth2Credentials {} + @Module + abstract static class LocalCredentialModule { + @Binds + @DefaultCredential + abstract GoogleCredentialsBundle provideLocalCredentialAsDefaultCredential( + @LocalCredential GoogleCredentialsBundle credential); + } + + /** Raised when we need a user login. */ + static class LoginRequiredException extends RuntimeException { + LoginRequiredException() {} + } } diff --git a/core/src/main/java/google/registry/tools/RequestFactoryModule.java b/core/src/main/java/google/registry/tools/RequestFactoryModule.java index f338e4f7f..1478fde62 100644 --- a/core/src/main/java/google/registry/tools/RequestFactoryModule.java +++ b/core/src/main/java/google/registry/tools/RequestFactoryModule.java @@ -14,13 +14,13 @@ package google.registry.tools; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.client.http.HttpRequestFactory; import com.google.api.client.http.javanet.NetHttpTransport; import dagger.Module; import dagger.Provides; import google.registry.config.CredentialModule.DefaultCredential; import google.registry.config.RegistryConfig; +import google.registry.util.GoogleCredentialsBundle; /** * Module for providing the HttpRequestFactory. @@ -30,12 +30,12 @@ import google.registry.config.RegistryConfig; */ @Module class RequestFactoryModule { - + static final int REQUEST_TIMEOUT_MS = 10 * 60 * 1000; @Provides static HttpRequestFactory provideHttpRequestFactory( - @DefaultCredential GoogleCredential credential) { + @DefaultCredential GoogleCredentialsBundle credentialsBundle) { if (RegistryConfig.areServersLocal()) { return new NetHttpTransport() .createRequestFactory( @@ -47,11 +47,12 @@ class RequestFactoryModule { return new NetHttpTransport() .createRequestFactory( request -> { - credential.initialize(request); + credentialsBundle.getHttpRequestInitializer().initialize(request); // GAE request times out after 10 min, so here we set the timeout to 10 min. This is // needed to support some nomulus commands like updating premium lists that take // a lot of time to complete. - // See https://developers.google.com/api-client-library/java/google-api-java-client/errors + // See + // https://developers.google.com/api-client-library/java/google-api-java-client/errors request.setConnectTimeout(REQUEST_TIMEOUT_MS); request.setReadTimeout(REQUEST_TIMEOUT_MS); }); diff --git a/core/src/test/java/google/registry/export/datastore/DatastoreAdminTest.java b/core/src/test/java/google/registry/export/datastore/DatastoreAdminTest.java index 459047ae0..99a2f1f9b 100644 --- a/core/src/test/java/google/registry/export/datastore/DatastoreAdminTest.java +++ b/core/src/test/java/google/registry/export/datastore/DatastoreAdminTest.java @@ -17,17 +17,17 @@ package google.registry.export.datastore; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth8.assertThat; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.client.http.GenericUrl; import com.google.api.client.http.HttpRequest; -import com.google.api.client.http.HttpTransport; -import com.google.api.client.http.javanet.NetHttpTransport; -import com.google.api.client.json.jackson2.JacksonFactory; +import com.google.auth.oauth2.AccessToken; +import com.google.auth.oauth2.GoogleCredentials; import com.google.common.collect.ImmutableList; import google.registry.testing.TestDataHelper; +import google.registry.util.GoogleCredentialsBundle; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.util.Date; import java.util.Optional; import org.junit.Before; import org.junit.Rule; @@ -48,27 +48,44 @@ public class DatastoreAdminTest { @Rule public final MockitoRule mocks = MockitoJUnit.rule(); - private HttpTransport httpTransport; - private GoogleCredential googleCredential; private DatastoreAdmin datastoreAdmin; + private static HttpRequest simulateSendRequest(HttpRequest httpRequest) { + try { + httpRequest.setUrl(new GenericUrl("https://localhost:65537")).execute(); + } catch (Exception expected) { + } + return httpRequest; + } + + private static Optional getAccessToken(HttpRequest httpRequest) { + return httpRequest.getHeaders().getAuthorizationAsList().stream() + .filter(header -> header.startsWith(AUTH_HEADER_PREFIX)) + .map(header -> header.substring(AUTH_HEADER_PREFIX.length())) + .findAny(); + } + + private static Optional getRequestContent(HttpRequest httpRequest) throws IOException { + if (httpRequest.getContent() == null) { + return Optional.empty(); + } + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + httpRequest.getContent().writeTo(outputStream); + outputStream.close(); + return Optional.of(outputStream.toString(StandardCharsets.UTF_8.name())); + } + @Before public void setup() { - httpTransport = new NetHttpTransport(); - googleCredential = - new GoogleCredential.Builder() - .setTransport(httpTransport) - .setJsonFactory(JacksonFactory.getDefaultInstance()) - .setClock(() -> 0) - .build(); - googleCredential.setAccessToken(ACCESS_TOKEN); - googleCredential.setExpiresInSeconds(1_000L); - + Date oneHourLater = new Date(System.currentTimeMillis() + 3_600_000); + GoogleCredentials googleCredentials = GoogleCredentials + .create(new AccessToken(ACCESS_TOKEN, oneHourLater)); + GoogleCredentialsBundle credentialsBundle = GoogleCredentialsBundle.create(googleCredentials); datastoreAdmin = new DatastoreAdmin.Builder( - googleCredential.getTransport(), - googleCredential.getJsonFactory(), - googleCredential) + credentialsBundle.getHttpTransport(), + credentialsBundle.getJsonFactory(), + credentialsBundle.getHttpRequestInitializer()) .setApplicationName("MyApplication") .setProjectId("MyCloudProject") .build(); @@ -151,29 +168,4 @@ public class DatastoreAdminTest { simulateSendRequest(httpRequest); assertThat(getAccessToken(httpRequest)).hasValue(ACCESS_TOKEN); } - - private static HttpRequest simulateSendRequest(HttpRequest httpRequest) { - try { - httpRequest.setUrl(new GenericUrl("https://localhost:65537")).execute(); - } catch (Exception expected) { - } - return httpRequest; - } - - private static Optional getAccessToken(HttpRequest httpRequest) { - return httpRequest.getHeaders().getAuthorizationAsList().stream() - .filter(header -> header.startsWith(AUTH_HEADER_PREFIX)) - .map(header -> header.substring(AUTH_HEADER_PREFIX.length())) - .findAny(); - } - - private static Optional getRequestContent(HttpRequest httpRequest) throws IOException { - if (httpRequest.getContent() == null) { - return Optional.empty(); - } - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - httpRequest.getContent().writeTo(outputStream); - outputStream.close(); - return Optional.of(outputStream.toString(StandardCharsets.UTF_8.name())); - } } diff --git a/core/src/test/java/google/registry/tools/RequestFactoryModuleTest.java b/core/src/test/java/google/registry/tools/RequestFactoryModuleTest.java index 8ff24d9a4..10e447d02 100644 --- a/core/src/test/java/google/registry/tools/RequestFactoryModuleTest.java +++ b/core/src/test/java/google/registry/tools/RequestFactoryModuleTest.java @@ -16,34 +16,40 @@ package google.registry.tools; import static com.google.common.truth.Truth.assertThat; import static google.registry.tools.RequestFactoryModule.REQUEST_TIMEOUT_MS; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.client.http.GenericUrl; import com.google.api.client.http.HttpRequest; import com.google.api.client.http.HttpRequestFactory; import com.google.api.client.http.HttpRequestInitializer; import google.registry.config.RegistryConfig; import google.registry.testing.SystemPropertyRule; +import google.registry.util.GoogleCredentialsBundle; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; @RunWith(JUnit4.class) public class RequestFactoryModuleTest { - private final GoogleCredential googleCredential = mock(GoogleCredential.class); - + @Rule public final MockitoRule mockitoRule = MockitoJUnit.rule(); @Rule public final SystemPropertyRule systemPropertyRule = new SystemPropertyRule(); + @Mock public GoogleCredentialsBundle credentialsBundle; + @Mock public HttpRequestInitializer httpRequestInitializer; + @Before public void setUp() { RegistryToolEnvironment.UNITTEST.setup(systemPropertyRule); + when(credentialsBundle.getHttpRequestInitializer()).thenReturn(httpRequestInitializer); } @Test @@ -52,12 +58,13 @@ public class RequestFactoryModuleTest { boolean origIsLocal = RegistryConfig.CONFIG_SETTINGS.get().appEngine.isLocal; RegistryConfig.CONFIG_SETTINGS.get().appEngine.isLocal = true; try { - HttpRequestFactory factory = RequestFactoryModule.provideHttpRequestFactory(googleCredential); + HttpRequestFactory factory = + RequestFactoryModule.provideHttpRequestFactory(credentialsBundle); HttpRequestInitializer initializer = factory.getInitializer(); assertThat(initializer).isNotNull(); HttpRequest request = factory.buildGetRequest(new GenericUrl("http://localhost")); initializer.initialize(request); - verifyZeroInteractions(googleCredential); + verifyZeroInteractions(httpRequestInitializer); } finally { RegistryConfig.CONFIG_SETTINGS.get().appEngine.isLocal = origIsLocal; } @@ -69,15 +76,16 @@ public class RequestFactoryModuleTest { boolean origIsLocal = RegistryConfig.CONFIG_SETTINGS.get().appEngine.isLocal; RegistryConfig.CONFIG_SETTINGS.get().appEngine.isLocal = false; try { - HttpRequestFactory factory = RequestFactoryModule.provideHttpRequestFactory(googleCredential); + HttpRequestFactory factory = + RequestFactoryModule.provideHttpRequestFactory(credentialsBundle); HttpRequestInitializer initializer = factory.getInitializer(); assertThat(initializer).isNotNull(); // HttpRequestFactory#buildGetRequest() calls initialize() once. HttpRequest request = factory.buildGetRequest(new GenericUrl("http://localhost")); - verify(googleCredential).initialize(request); + verify(httpRequestInitializer).initialize(request); assertThat(request.getConnectTimeout()).isEqualTo(REQUEST_TIMEOUT_MS); assertThat(request.getReadTimeout()).isEqualTo(REQUEST_TIMEOUT_MS); - verifyNoMoreInteractions(googleCredential); + verifyNoMoreInteractions(httpRequestInitializer); } finally { RegistryConfig.CONFIG_SETTINGS.get().appEngine.isLocal = origIsLocal; } diff --git a/package-lock.json b/package-lock.json index eaf7dd743..c655870d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", "dev": true, "requires": { - "mime-types": "2.1.24", + "mime-types": "~2.1.24", "negotiator": "0.6.2" } }, @@ -26,7 +26,7 @@ "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", "dev": true, "requires": { - "es6-promisify": "5.0.0" + "es6-promisify": "^5.0.0" } }, "anymatch": { @@ -35,8 +35,8 @@ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { - "micromatch": "3.1.10", - "normalize-path": "2.1.1" + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" }, "dependencies": { "normalize-path": { @@ -45,7 +45,7 @@ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { - "remove-trailing-separator": "1.1.0" + "remove-trailing-separator": "^1.0.1" } } } @@ -128,13 +128,13 @@ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, "requires": { - "cache-base": "1.0.1", - "class-utils": "0.3.6", - "component-emitter": "1.3.0", - "define-property": "1.0.0", - "isobject": "3.0.1", - "mixin-deep": "1.3.1", - "pascalcase": "0.1.1" + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" }, "dependencies": { "define-property": { @@ -143,7 +143,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -152,7 +152,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -161,7 +161,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -170,9 +170,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -223,15 +223,15 @@ "dev": true, "requires": { "bytes": "3.1.0", - "content-type": "1.0.4", + "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "1.1.2", + "depd": "~1.1.2", "http-errors": "1.7.2", "iconv-lite": "0.4.24", - "on-finished": "2.3.0", + "on-finished": "~2.3.0", "qs": "6.7.0", "raw-body": "2.4.0", - "type-is": "1.6.18" + "type-is": "~1.6.17" } }, "brace-expansion": { @@ -240,7 +240,7 @@ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -250,16 +250,16 @@ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { - "arr-flatten": "1.1.0", - "array-unique": "0.3.2", - "extend-shallow": "2.0.1", - "fill-range": "4.0.0", - "isobject": "3.0.1", - "repeat-element": "1.1.3", - "snapdragon": "0.8.2", - "snapdragon-node": "2.1.1", - "split-string": "3.1.0", - "to-regex": "3.0.2" + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" }, "dependencies": { "extend-shallow": { @@ -268,7 +268,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -279,8 +279,8 @@ "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", "dev": true, "requires": { - "buffer-alloc-unsafe": "1.1.0", - "buffer-fill": "1.0.0" + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" } }, "buffer-alloc-unsafe": { @@ -313,15 +313,15 @@ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "requires": { - "collection-visit": "1.0.0", - "component-emitter": "1.3.0", - "get-value": "2.0.6", - "has-value": "1.0.0", - "isobject": "3.0.1", - "set-value": "2.0.0", - "to-object-path": "0.3.0", - "union-value": "1.0.0", - "unset-value": "1.0.0" + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" } }, "callsite": { @@ -336,18 +336,18 @@ "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==", "dev": true, "requires": { - "anymatch": "2.0.0", - "async-each": "1.0.3", - "braces": "2.3.2", - "fsevents": "1.2.9", - "glob-parent": "3.1.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "4.0.1", - "normalize-path": "3.0.0", - "path-is-absolute": "1.0.1", - "readdirp": "2.2.1", - "upath": "1.1.2" + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" } }, "circular-json": { @@ -362,10 +362,10 @@ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "requires": { - "arr-union": "3.1.0", - "define-property": "0.2.5", - "isobject": "3.0.1", - "static-extend": "0.1.2" + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" }, "dependencies": { "define-property": { @@ -374,7 +374,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -385,8 +385,8 @@ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { - "map-visit": "1.0.0", - "object-visit": "1.0.1" + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" } }, "colors": { @@ -401,7 +401,7 @@ "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=", "dev": true, "requires": { - "lodash": "4.17.11" + "lodash": "^4.5.0" } }, "component-bind": { @@ -434,10 +434,10 @@ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "requires": { - "buffer-from": "1.1.1", - "inherits": "2.0.3", - "readable-stream": "2.3.6", - "typedarray": "0.0.6" + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" } }, "connect": { @@ -448,7 +448,7 @@ "requires": { "debug": "2.6.9", "finalhandler": "1.1.2", - "parseurl": "1.3.3", + "parseurl": "~1.3.3", "utils-merge": "1.0.1" } }, @@ -515,8 +515,8 @@ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "requires": { - "is-descriptor": "1.0.2", - "isobject": "3.0.1" + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" }, "dependencies": { "is-accessor-descriptor": { @@ -525,7 +525,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -534,7 +534,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -543,9 +543,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -568,10 +568,10 @@ "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", "dev": true, "requires": { - "custom-event": "1.0.1", - "ent": "2.2.0", - "extend": "3.0.2", - "void-elements": "2.0.1" + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" } }, "ee-first": { @@ -592,12 +592,12 @@ "integrity": "sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==", "dev": true, "requires": { - "accepts": "1.3.7", + "accepts": "~1.3.4", "base64id": "1.0.0", "cookie": "0.3.1", - "debug": "3.1.0", - "engine.io-parser": "2.1.3", - "ws": "3.3.3" + "debug": "~3.1.0", + "engine.io-parser": "~2.1.0", + "ws": "~3.3.1" }, "dependencies": { "debug": { @@ -619,14 +619,14 @@ "requires": { "component-emitter": "1.2.1", "component-inherit": "0.0.3", - "debug": "3.1.0", - "engine.io-parser": "2.1.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.1", "has-cors": "1.1.0", "indexof": "0.0.1", "parseqs": "0.0.5", "parseuri": "0.0.5", - "ws": "3.3.3", - "xmlhttprequest-ssl": "1.5.5", + "ws": "~3.3.1", + "xmlhttprequest-ssl": "~1.5.4", "yeast": "0.1.2" }, "dependencies": { @@ -654,10 +654,10 @@ "dev": true, "requires": { "after": "0.8.2", - "arraybuffer.slice": "0.0.7", + "arraybuffer.slice": "~0.0.7", "base64-arraybuffer": "0.1.5", "blob": "0.0.5", - "has-binary2": "1.0.3" + "has-binary2": "~1.0.2" } }, "ent": { @@ -678,7 +678,7 @@ "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", "dev": true, "requires": { - "es6-promise": "4.2.8" + "es6-promise": "^4.0.3" } }, "escape-html": { @@ -699,9 +699,9 @@ "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=", "dev": true, "requires": { - "array-slice": "0.2.3", - "array-unique": "0.2.1", - "braces": "0.1.5" + "array-slice": "^0.2.3", + "array-unique": "^0.2.1", + "braces": "^0.1.2" }, "dependencies": { "array-unique": { @@ -716,7 +716,7 @@ "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=", "dev": true, "requires": { - "expand-range": "0.1.1" + "expand-range": "^0.1.0" } } } @@ -727,13 +727,13 @@ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "posix-character-classes": "0.1.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -742,7 +742,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -751,7 +751,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -762,8 +762,8 @@ "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", "dev": true, "requires": { - "is-number": "0.1.1", - "repeat-string": "0.2.2" + "is-number": "^0.1.1", + "repeat-string": "^0.2.2" }, "dependencies": { "is-number": { @@ -792,8 +792,8 @@ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { - "assign-symbols": "1.0.0", - "is-extendable": "1.0.1" + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { @@ -802,7 +802,7 @@ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { - "is-plain-object": "2.0.4" + "is-plain-object": "^2.0.4" } } } @@ -813,14 +813,14 @@ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "requires": { - "array-unique": "0.3.2", - "define-property": "1.0.0", - "expand-brackets": "2.1.4", - "extend-shallow": "2.0.1", - "fragment-cache": "0.2.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -829,7 +829,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "extend-shallow": { @@ -838,7 +838,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "is-accessor-descriptor": { @@ -847,7 +847,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -856,7 +856,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -865,9 +865,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -890,7 +890,7 @@ "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", "dev": true, "requires": { - "pend": "1.2.0" + "pend": "~1.2.0" } }, "fill-range": { @@ -899,10 +899,10 @@ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "extend-shallow": "2.0.1", - "is-number": "3.0.0", - "repeat-string": "1.6.1", - "to-regex-range": "2.1.1" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" }, "dependencies": { "extend-shallow": { @@ -911,7 +911,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -923,12 +923,12 @@ "dev": true, "requires": { "debug": "2.6.9", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "parseurl": "1.3.3", - "statuses": "1.5.0", - "unpipe": "1.0.0" + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" } }, "follow-redirects": { @@ -937,7 +937,7 @@ "integrity": "sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==", "dev": true, "requires": { - "debug": "3.2.6" + "debug": "^3.2.6" }, "dependencies": { "debug": { @@ -946,7 +946,7 @@ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { - "ms": "2.1.2" + "ms": "^2.1.1" } }, "ms": { @@ -969,7 +969,7 @@ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, "requires": { - "map-cache": "0.2.2" + "map-cache": "^0.2.2" } }, "fs-access": { @@ -978,7 +978,7 @@ "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", "dev": true, "requires": { - "null-check": "1.0.0" + "null-check": "^1.0.0" } }, "fs.realpath": { @@ -994,8 +994,8 @@ "dev": true, "optional": true, "requires": { - "nan": "2.14.0", - "node-pre-gyp": "0.12.0" + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" }, "dependencies": { "abbrev": { @@ -1021,8 +1021,8 @@ "dev": true, "optional": true, "requires": { - "delegates": "1.0.0", - "readable-stream": "2.3.6" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } }, "balanced-match": { @@ -1035,7 +1035,7 @@ "bundled": true, "dev": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -1072,7 +1072,7 @@ "dev": true, "optional": true, "requires": { - "ms": "2.1.1" + "ms": "^2.1.1" } }, "deep-extend": { @@ -1099,7 +1099,7 @@ "dev": true, "optional": true, "requires": { - "minipass": "2.3.5" + "minipass": "^2.2.1" } }, "fs.realpath": { @@ -1114,14 +1114,14 @@ "dev": true, "optional": true, "requires": { - "aproba": "1.2.0", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.3" + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" } }, "glob": { @@ -1130,12 +1130,12 @@ "dev": true, "optional": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "has-unicode": { @@ -1150,7 +1150,7 @@ "dev": true, "optional": true, "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } }, "ignore-walk": { @@ -1159,7 +1159,7 @@ "dev": true, "optional": true, "requires": { - "minimatch": "3.0.4" + "minimatch": "^3.0.4" } }, "inflight": { @@ -1168,8 +1168,8 @@ "dev": true, "optional": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -1188,7 +1188,7 @@ "bundled": true, "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "isarray": { @@ -1202,7 +1202,7 @@ "bundled": true, "dev": true, "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -1215,8 +1215,8 @@ "bundled": true, "dev": true, "requires": { - "safe-buffer": "5.1.2", - "yallist": "3.0.3" + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" } }, "minizlib": { @@ -1225,7 +1225,7 @@ "dev": true, "optional": true, "requires": { - "minipass": "2.3.5" + "minipass": "^2.2.1" } }, "mkdirp": { @@ -1248,9 +1248,9 @@ "dev": true, "optional": true, "requires": { - "debug": "4.1.1", - "iconv-lite": "0.4.24", - "sax": "1.2.4" + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" } }, "node-pre-gyp": { @@ -1259,16 +1259,16 @@ "dev": true, "optional": true, "requires": { - "detect-libc": "1.0.3", - "mkdirp": "0.5.1", - "needle": "2.3.0", - "nopt": "4.0.1", - "npm-packlist": "1.4.1", - "npmlog": "4.1.2", - "rc": "1.2.8", - "rimraf": "2.6.3", - "semver": "5.7.0", - "tar": "4.4.8" + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" } }, "nopt": { @@ -1277,8 +1277,8 @@ "dev": true, "optional": true, "requires": { - "abbrev": "1.1.1", - "osenv": "0.1.5" + "abbrev": "1", + "osenv": "^0.1.4" } }, "npm-bundled": { @@ -1293,8 +1293,8 @@ "dev": true, "optional": true, "requires": { - "ignore-walk": "3.0.1", - "npm-bundled": "1.0.6" + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" } }, "npmlog": { @@ -1303,10 +1303,10 @@ "dev": true, "optional": true, "requires": { - "are-we-there-yet": "1.1.5", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" } }, "number-is-nan": { @@ -1325,7 +1325,7 @@ "bundled": true, "dev": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "os-homedir": { @@ -1346,8 +1346,8 @@ "dev": true, "optional": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" } }, "path-is-absolute": { @@ -1368,10 +1368,10 @@ "dev": true, "optional": true, "requires": { - "deep-extend": "0.6.0", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" }, "dependencies": { "minimist": { @@ -1388,13 +1388,13 @@ "dev": true, "optional": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "rimraf": { @@ -1403,7 +1403,7 @@ "dev": true, "optional": true, "requires": { - "glob": "7.1.3" + "glob": "^7.1.3" } }, "safe-buffer": { @@ -1446,9 +1446,9 @@ "bundled": true, "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string_decoder": { @@ -1457,7 +1457,7 @@ "dev": true, "optional": true, "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "~5.1.0" } }, "strip-ansi": { @@ -1465,7 +1465,7 @@ "bundled": true, "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-json-comments": { @@ -1480,13 +1480,13 @@ "dev": true, "optional": true, "requires": { - "chownr": "1.1.1", - "fs-minipass": "1.2.5", - "minipass": "2.3.5", - "minizlib": "1.2.1", - "mkdirp": "0.5.1", - "safe-buffer": "5.1.2", - "yallist": "3.0.3" + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" } }, "util-deprecate": { @@ -1501,7 +1501,7 @@ "dev": true, "optional": true, "requires": { - "string-width": "1.0.2" + "string-width": "^1.0.2 || 2" } }, "wrappy": { @@ -1528,12 +1528,12 @@ "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", "dev": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "glob-parent": { @@ -1542,8 +1542,8 @@ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" }, "dependencies": { "is-glob": { @@ -1552,7 +1552,7 @@ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.0" } } } @@ -1597,9 +1597,9 @@ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, "requires": { - "get-value": "2.0.6", - "has-values": "1.0.0", - "isobject": "3.0.1" + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" } }, "has-values": { @@ -1608,8 +1608,8 @@ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" + "is-number": "^3.0.0", + "kind-of": "^4.0.0" }, "dependencies": { "kind-of": { @@ -1618,7 +1618,7 @@ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1629,10 +1629,10 @@ "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", "dev": true, "requires": { - "depd": "1.1.2", + "depd": "~1.1.2", "inherits": "2.0.3", "setprototypeof": "1.1.1", - "statuses": "1.5.0", + "statuses": ">= 1.5.0 < 2", "toidentifier": "1.0.0" } }, @@ -1642,9 +1642,9 @@ "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", "dev": true, "requires": { - "eventemitter3": "3.1.2", - "follow-redirects": "1.7.0", - "requires-port": "1.0.0" + "eventemitter3": "^3.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" } }, "https-proxy-agent": { @@ -1653,8 +1653,8 @@ "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", "dev": true, "requires": { - "agent-base": "4.3.0", - "debug": "3.2.6" + "agent-base": "^4.1.0", + "debug": "^3.1.0" }, "dependencies": { "debug": { @@ -1663,7 +1663,7 @@ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { - "ms": "2.1.2" + "ms": "^2.1.1" } }, "ms": { @@ -1680,7 +1680,7 @@ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } }, "indexof": { @@ -1695,8 +1695,8 @@ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -1711,7 +1711,7 @@ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -1720,7 +1720,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1731,7 +1731,7 @@ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { - "binary-extensions": "1.13.1" + "binary-extensions": "^1.0.0" } }, "is-buffer": { @@ -1746,7 +1746,7 @@ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -1755,7 +1755,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1766,9 +1766,9 @@ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" }, "dependencies": { "kind-of": { @@ -1797,7 +1797,7 @@ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.1" } }, "is-number": { @@ -1806,7 +1806,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -1815,7 +1815,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1826,7 +1826,7 @@ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" } }, "is-windows": { @@ -1847,7 +1847,7 @@ "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==", "dev": true, "requires": { - "buffer-alloc": "1.2.0" + "buffer-alloc": "^1.2.0" } }, "isexe": { @@ -1874,31 +1874,31 @@ "integrity": "sha512-ZTjyuDXVXhXsvJ1E4CnZzbCjSxD6sEdzEsFYogLuZM0yqvg/mgz+O+R1jb0J7uAQeuzdY8kJgx6hSNXLwFuHIQ==", "dev": true, "requires": { - "bluebird": "3.5.5", - "body-parser": "1.19.0", - "chokidar": "2.1.6", - "colors": "1.3.3", - "combine-lists": "1.0.1", - "connect": "3.7.0", - "core-js": "2.6.9", - "di": "0.0.1", - "dom-serialize": "2.2.1", - "expand-braces": "0.1.2", - "glob": "7.1.4", - "graceful-fs": "4.1.15", - "http-proxy": "1.17.0", - "isbinaryfile": "3.0.3", - "lodash": "4.17.11", - "log4js": "3.0.6", - "mime": "2.4.4", - "minimatch": "3.0.4", - "optimist": "0.6.1", - "qjobs": "1.2.0", - "range-parser": "1.2.1", - "rimraf": "2.6.3", - "safe-buffer": "5.1.2", + "bluebird": "^3.3.0", + "body-parser": "^1.16.1", + "chokidar": "^2.0.3", + "colors": "^1.1.0", + "combine-lists": "^1.0.0", + "connect": "^3.6.0", + "core-js": "^2.2.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.0", + "expand-braces": "^0.1.1", + "glob": "^7.1.1", + "graceful-fs": "^4.1.2", + "http-proxy": "^1.13.0", + "isbinaryfile": "^3.0.0", + "lodash": "^4.17.4", + "log4js": "^3.0.0", + "mime": "^2.3.1", + "minimatch": "^3.0.2", + "optimist": "^0.6.1", + "qjobs": "^1.1.4", + "range-parser": "^1.2.0", + "rimraf": "^2.6.0", + "safe-buffer": "^5.0.1", "socket.io": "2.1.1", - "source-map": "0.6.1", + "source-map": "^0.6.1", "tmp": "0.0.33", "useragent": "2.2.1" } @@ -1909,8 +1909,8 @@ "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==", "dev": true, "requires": { - "fs-access": "1.0.1", - "which": "1.3.1" + "fs-access": "^1.0.0", + "which": "^1.2.1" } }, "karma-closure": { @@ -1925,7 +1925,7 @@ "integrity": "sha512-iuC0hmr9b+SNn1DaUD2QEYtUxkS1J+bSJSn7ejdEexs7P8EYvA1CWkEdrDQ+8jVH3AgWlCNwjYsT1chjcNW9lA==", "dev": true, "requires": { - "jasmine-core": "3.4.0" + "jasmine-core": "^3.3" } }, "kind-of": { @@ -1946,10 +1946,10 @@ "integrity": "sha512-ezXZk6oPJCWL483zj64pNkMuY/NcRX5MPiB0zE6tjZM137aeusrOnW1ecxgF9cmwMWkBMhjteQxBPoZBh9FDxQ==", "dev": true, "requires": { - "circular-json": "0.5.9", - "date-format": "1.2.0", - "debug": "3.2.6", - "rfdc": "1.1.4", + "circular-json": "^0.5.5", + "date-format": "^1.2.0", + "debug": "^3.1.0", + "rfdc": "^1.1.2", "streamroller": "0.7.0" }, "dependencies": { @@ -1959,7 +1959,7 @@ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { - "ms": "2.1.2" + "ms": "^2.1.1" } }, "ms": { @@ -1988,7 +1988,7 @@ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, "requires": { - "object-visit": "1.0.1" + "object-visit": "^1.0.0" } }, "media-typer": { @@ -2003,19 +2003,19 @@ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "braces": "2.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "extglob": "2.0.4", - "fragment-cache": "0.2.1", - "kind-of": "6.0.2", - "nanomatch": "1.2.13", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" } }, "mime": { @@ -2045,7 +2045,7 @@ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -2060,8 +2060,8 @@ "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", "dev": true, "requires": { - "for-in": "1.0.2", - "is-extendable": "1.0.1" + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { @@ -2070,7 +2070,7 @@ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { - "is-plain-object": "2.0.4" + "is-plain-object": "^2.0.4" } } } @@ -2103,17 +2103,17 @@ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "fragment-cache": "0.2.1", - "is-windows": "1.0.2", - "kind-of": "6.0.2", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" } }, "negotiator": { @@ -2146,9 +2146,9 @@ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, "requires": { - "copy-descriptor": "0.1.1", - "define-property": "0.2.5", - "kind-of": "3.2.2" + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" }, "dependencies": { "define-property": { @@ -2157,7 +2157,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "kind-of": { @@ -2166,7 +2166,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -2177,7 +2177,7 @@ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.0" } }, "object.pick": { @@ -2186,7 +2186,7 @@ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" } }, "on-finished": { @@ -2204,7 +2204,7 @@ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "optimist": { @@ -2213,8 +2213,8 @@ "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "dev": true, "requires": { - "minimist": "0.0.8", - "wordwrap": "0.0.3" + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" } }, "os-tmpdir": { @@ -2229,7 +2229,7 @@ "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", "dev": true, "requires": { - "better-assert": "1.0.2" + "better-assert": "~1.0.0" } }, "parseuri": { @@ -2238,7 +2238,7 @@ "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", "dev": true, "requires": { - "better-assert": "1.0.2" + "better-assert": "~1.0.0" } }, "parseurl": { @@ -2301,14 +2301,14 @@ "integrity": "sha512-3EXZSximCzxuVKpIHtyec8Wm2dWZn1fc5tQi34qWfiUgubEVYHjUvr0GOJojqf3mifI6oyKnCdrGxaOI+lWReA==", "dev": true, "requires": { - "debug": "4.1.1", - "extract-zip": "1.6.7", - "https-proxy-agent": "2.2.1", - "mime": "2.4.4", - "progress": "2.0.3", - "proxy-from-env": "1.0.0", - "rimraf": "2.6.3", - "ws": "6.2.1" + "debug": "^4.1.0", + "extract-zip": "^1.6.6", + "https-proxy-agent": "^2.2.1", + "mime": "^2.0.3", + "progress": "^2.0.1", + "proxy-from-env": "^1.0.0", + "rimraf": "^2.6.1", + "ws": "^6.1.0" }, "dependencies": { "debug": { @@ -2317,7 +2317,7 @@ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { - "ms": "2.1.2" + "ms": "^2.1.1" } }, "ms": { @@ -2332,7 +2332,7 @@ "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", "dev": true, "requires": { - "async-limiter": "1.0.0" + "async-limiter": "~1.0.0" } } } @@ -2373,13 +2373,13 @@ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.1", - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "readdirp": { @@ -2388,9 +2388,9 @@ "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "dev": true, "requires": { - "graceful-fs": "4.1.15", - "micromatch": "3.1.10", - "readable-stream": "2.3.6" + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" } }, "regex-not": { @@ -2399,8 +2399,8 @@ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, "requires": { - "extend-shallow": "3.0.2", - "safe-regex": "1.1.0" + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" } }, "remove-trailing-separator": { @@ -2451,7 +2451,7 @@ "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "requires": { - "glob": "7.1.4" + "glob": "^7.1.3" } }, "safe-buffer": { @@ -2466,7 +2466,7 @@ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { - "ret": "0.1.15" + "ret": "~0.1.10" } }, "safer-buffer": { @@ -2481,10 +2481,10 @@ "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", "dev": true, "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "split-string": "3.1.0" + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" }, "dependencies": { "extend-shallow": { @@ -2493,7 +2493,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -2510,14 +2510,14 @@ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, "requires": { - "base": "0.11.2", - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "map-cache": "0.2.2", - "source-map": "0.5.7", - "source-map-resolve": "0.5.2", - "use": "3.1.1" + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" }, "dependencies": { "define-property": { @@ -2526,7 +2526,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -2535,7 +2535,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "source-map": { @@ -2552,9 +2552,9 @@ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, "requires": { - "define-property": "1.0.0", - "isobject": "3.0.1", - "snapdragon-util": "3.0.1" + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" }, "dependencies": { "define-property": { @@ -2563,7 +2563,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -2572,7 +2572,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -2581,7 +2581,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -2590,9 +2590,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -2603,7 +2603,7 @@ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.2.0" }, "dependencies": { "kind-of": { @@ -2612,7 +2612,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -2623,12 +2623,12 @@ "integrity": "sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==", "dev": true, "requires": { - "debug": "3.1.0", - "engine.io": "3.2.1", - "has-binary2": "1.0.3", - "socket.io-adapter": "1.1.1", + "debug": "~3.1.0", + "engine.io": "~3.2.0", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", "socket.io-client": "2.1.1", - "socket.io-parser": "3.2.0" + "socket.io-parser": "~3.2.0" }, "dependencies": { "debug": { @@ -2658,15 +2658,15 @@ "base64-arraybuffer": "0.1.5", "component-bind": "1.0.0", "component-emitter": "1.2.1", - "debug": "3.1.0", - "engine.io-client": "3.2.1", - "has-binary2": "1.0.3", + "debug": "~3.1.0", + "engine.io-client": "~3.2.0", + "has-binary2": "~1.0.2", "has-cors": "1.1.0", "indexof": "0.0.1", "object-component": "0.0.3", "parseqs": "0.0.5", "parseuri": "0.0.5", - "socket.io-parser": "3.2.0", + "socket.io-parser": "~3.2.0", "to-array": "0.1.4" }, "dependencies": { @@ -2694,7 +2694,7 @@ "dev": true, "requires": { "component-emitter": "1.2.1", - "debug": "3.1.0", + "debug": "~3.1.0", "isarray": "2.0.1" }, "dependencies": { @@ -2733,11 +2733,11 @@ "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", "dev": true, "requires": { - "atob": "2.1.2", - "decode-uri-component": "0.2.0", - "resolve-url": "0.2.1", - "source-map-url": "0.4.0", - "urix": "0.1.0" + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" } }, "source-map-url": { @@ -2752,7 +2752,7 @@ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, "requires": { - "extend-shallow": "3.0.2" + "extend-shallow": "^3.0.0" } }, "static-extend": { @@ -2761,8 +2761,8 @@ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, "requires": { - "define-property": "0.2.5", - "object-copy": "0.1.0" + "define-property": "^0.2.5", + "object-copy": "^0.1.0" }, "dependencies": { "define-property": { @@ -2771,7 +2771,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -2788,10 +2788,10 @@ "integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==", "dev": true, "requires": { - "date-format": "1.2.0", - "debug": "3.2.6", - "mkdirp": "0.5.1", - "readable-stream": "2.3.6" + "date-format": "^1.2.0", + "debug": "^3.1.0", + "mkdirp": "^0.5.1", + "readable-stream": "^2.3.0" }, "dependencies": { "debug": { @@ -2800,7 +2800,7 @@ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { - "ms": "2.1.2" + "ms": "^2.1.1" } }, "ms": { @@ -2817,7 +2817,7 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "~5.1.0" } }, "tmp": { @@ -2826,7 +2826,7 @@ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { - "os-tmpdir": "1.0.2" + "os-tmpdir": "~1.0.2" } }, "to-array": { @@ -2841,7 +2841,7 @@ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -2850,7 +2850,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -2861,10 +2861,10 @@ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, "requires": { - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "regex-not": "1.0.2", - "safe-regex": "1.1.0" + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" } }, "to-regex-range": { @@ -2873,8 +2873,8 @@ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "requires": { - "is-number": "3.0.0", - "repeat-string": "1.6.1" + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" } }, "toidentifier": { @@ -2890,7 +2890,7 @@ "dev": true, "requires": { "media-typer": "0.3.0", - "mime-types": "2.1.24" + "mime-types": "~2.1.24" } }, "typedarray": { @@ -2911,10 +2911,10 @@ "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", "dev": true, "requires": { - "arr-union": "3.1.0", - "get-value": "2.0.6", - "is-extendable": "0.1.1", - "set-value": "0.4.3" + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" }, "dependencies": { "extend-shallow": { @@ -2923,7 +2923,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "set-value": { @@ -2932,10 +2932,10 @@ "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", "dev": true, "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "to-object-path": "0.3.0" + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" } } } @@ -2952,8 +2952,8 @@ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, "requires": { - "has-value": "0.3.1", - "isobject": "3.0.1" + "has-value": "^0.3.1", + "isobject": "^3.0.0" }, "dependencies": { "has-value": { @@ -2962,9 +2962,9 @@ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, "requires": { - "get-value": "2.0.6", - "has-values": "0.1.4", - "isobject": "2.1.0" + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" }, "dependencies": { "isobject": { @@ -3010,8 +3010,8 @@ "integrity": "sha1-z1k+9PLRdYdei7ZY6pLhik/QbY4=", "dev": true, "requires": { - "lru-cache": "2.2.4", - "tmp": "0.0.33" + "lru-cache": "2.2.x", + "tmp": "0.0.x" } }, "util-deprecate": { @@ -3038,7 +3038,7 @@ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "requires": { - "isexe": "2.0.0" + "isexe": "^2.0.0" } }, "wordwrap": { @@ -3059,9 +3059,9 @@ "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", "dev": true, "requires": { - "async-limiter": "1.0.0", - "safe-buffer": "5.1.2", - "ultron": "1.1.1" + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" } }, "xmlhttprequest-ssl": { @@ -3076,7 +3076,7 @@ "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", "dev": true, "requires": { - "fd-slicer": "1.0.1" + "fd-slicer": "~1.0.1" } }, "yeast": { diff --git a/proxy/build.gradle b/proxy/build.gradle index dc4957acf..859199d8e 100644 --- a/proxy/build.gradle +++ b/proxy/build.gradle @@ -12,6 +12,8 @@ dependencies { compile deps['com.google.apis:google-api-services-cloudkms'] compile deps['com.google.apis:google-api-services-monitoring'] compile deps['com.google.apis:google-api-services-storage'] + compile deps['com.google.auth:google-auth-library-credentials'] + compile deps['com.google.auth:google-auth-library-oauth2-http'] compile deps['com.google.auto.value:auto-value-annotations'] compile deps['com.google.code.findbugs:jsr305'] compile deps['com.google.code.gson:gson'] diff --git a/proxy/gradle/dependency-locks/compile.lockfile b/proxy/gradle/dependency-locks/compile.lockfile index 051663997..2eb2304cc 100644 --- a/proxy/gradle/dependency-locks/compile.lockfile +++ b/proxy/gradle/dependency-locks/compile.lockfile @@ -2,13 +2,15 @@ # Manual edits can break the build and are not advised. # This file is expected to be part of source control. com.beust:jcommander:1.60 -com.fasterxml.jackson.core:jackson-core:2.9.6 +com.fasterxml.jackson.core:jackson-core:2.9.9 com.google.api-client:google-api-client:1.29.2 com.google.apis:google-api-services-cloudkms:v1-rev12-1.22.0 com.google.apis:google-api-services-monitoring:v3-rev426-1.23.0 com.google.apis:google-api-services-storage:v1-rev150-1.22.0 com.google.appengine:appengine-api-1.0-sdk:1.9.48 com.google.appengine:appengine-testing:1.9.58 +com.google.auth:google-auth-library-credentials:0.16.1 +com.google.auth:google-auth-library-oauth2-http:0.16.1 com.google.auto.value:auto-value-annotations:1.6.3 com.google.auto.value:auto-value:1.6.3 com.google.code.findbugs:jsr305:3.0.2 @@ -19,17 +21,17 @@ com.google.flogger:flogger:0.1 com.google.guava:failureaccess:1.0.1 com.google.guava:guava:27.1-jre com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava -com.google.http-client:google-http-client-jackson2:1.29.2 -com.google.http-client:google-http-client:1.29.2 -com.google.j2objc:j2objc-annotations:1.1 +com.google.http-client:google-http-client-jackson2:1.30.1 +com.google.http-client:google-http-client:1.30.1 +com.google.j2objc:j2objc-annotations:1.3 com.google.monitoring-client:metrics:1.0.4 com.google.monitoring-client:stackdriver:1.0.4 com.google.oauth-client:google-oauth-client:1.29.2 com.google.re2j:re2j:1.1 com.ibm.icu:icu4j:57.1 -commons-codec:commons-codec:1.10 +commons-codec:commons-codec:1.11 commons-logging:commons-logging:1.2 -io.grpc:grpc-context:1.18.0 +io.grpc:grpc-context:1.19.0 io.netty:netty-buffer:4.1.31.Final io.netty:netty-codec-http:4.1.31.Final io.netty:netty-codec:4.1.31.Final @@ -37,15 +39,15 @@ io.netty:netty-common:4.1.31.Final io.netty:netty-handler:4.1.31.Final io.netty:netty-resolver:4.1.31.Final io.netty:netty-transport:4.1.31.Final -io.opencensus:opencensus-api:0.19.2 -io.opencensus:opencensus-contrib-http-util:0.19.2 +io.opencensus:opencensus-api:0.21.0 +io.opencensus:opencensus-contrib-http-util:0.21.0 javax.activation:activation:1.1 javax.inject:javax.inject:1 javax.mail:mail:1.4 javax.xml.bind:jaxb-api:2.3.0 joda-time:joda-time:2.9.2 -org.apache.httpcomponents:httpclient:4.5.5 -org.apache.httpcomponents:httpcore:4.4.9 +org.apache.httpcomponents:httpclient:4.5.8 +org.apache.httpcomponents:httpcore:4.4.11 org.bouncycastle:bcpkix-jdk15on:1.61 org.bouncycastle:bcprov-jdk15on:1.61 org.checkerframework:checker-qual:2.5.2 diff --git a/proxy/gradle/dependency-locks/compileClasspath.lockfile b/proxy/gradle/dependency-locks/compileClasspath.lockfile index 051663997..2eb2304cc 100644 --- a/proxy/gradle/dependency-locks/compileClasspath.lockfile +++ b/proxy/gradle/dependency-locks/compileClasspath.lockfile @@ -2,13 +2,15 @@ # Manual edits can break the build and are not advised. # This file is expected to be part of source control. com.beust:jcommander:1.60 -com.fasterxml.jackson.core:jackson-core:2.9.6 +com.fasterxml.jackson.core:jackson-core:2.9.9 com.google.api-client:google-api-client:1.29.2 com.google.apis:google-api-services-cloudkms:v1-rev12-1.22.0 com.google.apis:google-api-services-monitoring:v3-rev426-1.23.0 com.google.apis:google-api-services-storage:v1-rev150-1.22.0 com.google.appengine:appengine-api-1.0-sdk:1.9.48 com.google.appengine:appengine-testing:1.9.58 +com.google.auth:google-auth-library-credentials:0.16.1 +com.google.auth:google-auth-library-oauth2-http:0.16.1 com.google.auto.value:auto-value-annotations:1.6.3 com.google.auto.value:auto-value:1.6.3 com.google.code.findbugs:jsr305:3.0.2 @@ -19,17 +21,17 @@ com.google.flogger:flogger:0.1 com.google.guava:failureaccess:1.0.1 com.google.guava:guava:27.1-jre com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava -com.google.http-client:google-http-client-jackson2:1.29.2 -com.google.http-client:google-http-client:1.29.2 -com.google.j2objc:j2objc-annotations:1.1 +com.google.http-client:google-http-client-jackson2:1.30.1 +com.google.http-client:google-http-client:1.30.1 +com.google.j2objc:j2objc-annotations:1.3 com.google.monitoring-client:metrics:1.0.4 com.google.monitoring-client:stackdriver:1.0.4 com.google.oauth-client:google-oauth-client:1.29.2 com.google.re2j:re2j:1.1 com.ibm.icu:icu4j:57.1 -commons-codec:commons-codec:1.10 +commons-codec:commons-codec:1.11 commons-logging:commons-logging:1.2 -io.grpc:grpc-context:1.18.0 +io.grpc:grpc-context:1.19.0 io.netty:netty-buffer:4.1.31.Final io.netty:netty-codec-http:4.1.31.Final io.netty:netty-codec:4.1.31.Final @@ -37,15 +39,15 @@ io.netty:netty-common:4.1.31.Final io.netty:netty-handler:4.1.31.Final io.netty:netty-resolver:4.1.31.Final io.netty:netty-transport:4.1.31.Final -io.opencensus:opencensus-api:0.19.2 -io.opencensus:opencensus-contrib-http-util:0.19.2 +io.opencensus:opencensus-api:0.21.0 +io.opencensus:opencensus-contrib-http-util:0.21.0 javax.activation:activation:1.1 javax.inject:javax.inject:1 javax.mail:mail:1.4 javax.xml.bind:jaxb-api:2.3.0 joda-time:joda-time:2.9.2 -org.apache.httpcomponents:httpclient:4.5.5 -org.apache.httpcomponents:httpcore:4.4.9 +org.apache.httpcomponents:httpclient:4.5.8 +org.apache.httpcomponents:httpcore:4.4.11 org.bouncycastle:bcpkix-jdk15on:1.61 org.bouncycastle:bcprov-jdk15on:1.61 org.checkerframework:checker-qual:2.5.2 diff --git a/proxy/gradle/dependency-locks/runtimeClasspath.lockfile b/proxy/gradle/dependency-locks/runtimeClasspath.lockfile index 3e9925fcb..5ccdf04f1 100644 --- a/proxy/gradle/dependency-locks/runtimeClasspath.lockfile +++ b/proxy/gradle/dependency-locks/runtimeClasspath.lockfile @@ -2,13 +2,15 @@ # Manual edits can break the build and are not advised. # This file is expected to be part of source control. com.beust:jcommander:1.60 -com.fasterxml.jackson.core:jackson-core:2.9.6 +com.fasterxml.jackson.core:jackson-core:2.9.9 com.google.api-client:google-api-client:1.29.2 com.google.apis:google-api-services-cloudkms:v1-rev12-1.22.0 com.google.apis:google-api-services-monitoring:v3-rev426-1.23.0 com.google.apis:google-api-services-storage:v1-rev150-1.22.0 com.google.appengine:appengine-api-1.0-sdk:1.9.48 com.google.appengine:appengine-testing:1.9.58 +com.google.auth:google-auth-library-credentials:0.16.1 +com.google.auth:google-auth-library-oauth2-http:0.16.1 com.google.auto.value:auto-value-annotations:1.6.3 com.google.auto.value:auto-value:1.6.3 com.google.code.findbugs:jsr305:3.0.2 @@ -20,17 +22,17 @@ com.google.flogger:flogger:0.1 com.google.guava:failureaccess:1.0.1 com.google.guava:guava:27.1-jre com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava -com.google.http-client:google-http-client-jackson2:1.29.2 -com.google.http-client:google-http-client:1.29.2 -com.google.j2objc:j2objc-annotations:1.1 +com.google.http-client:google-http-client-jackson2:1.30.1 +com.google.http-client:google-http-client:1.30.1 +com.google.j2objc:j2objc-annotations:1.3 com.google.monitoring-client:metrics:1.0.4 com.google.monitoring-client:stackdriver:1.0.4 com.google.oauth-client:google-oauth-client:1.29.2 com.google.re2j:re2j:1.1 com.ibm.icu:icu4j:57.1 -commons-codec:commons-codec:1.10 +commons-codec:commons-codec:1.11 commons-logging:commons-logging:1.2 -io.grpc:grpc-context:1.18.0 +io.grpc:grpc-context:1.19.0 io.netty:netty-buffer:4.1.31.Final io.netty:netty-codec-http:4.1.31.Final io.netty:netty-codec:4.1.31.Final @@ -39,15 +41,15 @@ io.netty:netty-handler:4.1.31.Final io.netty:netty-resolver:4.1.31.Final io.netty:netty-tcnative-boringssl-static:2.0.22.Final io.netty:netty-transport:4.1.31.Final -io.opencensus:opencensus-api:0.19.2 -io.opencensus:opencensus-contrib-http-util:0.19.2 +io.opencensus:opencensus-api:0.21.0 +io.opencensus:opencensus-contrib-http-util:0.21.0 javax.activation:activation:1.1 javax.inject:javax.inject:1 javax.mail:mail:1.4 javax.xml.bind:jaxb-api:2.3.0 joda-time:joda-time:2.9.2 -org.apache.httpcomponents:httpclient:4.5.5 -org.apache.httpcomponents:httpcore:4.4.9 +org.apache.httpcomponents:httpclient:4.5.8 +org.apache.httpcomponents:httpcore:4.4.11 org.bouncycastle:bcpkix-jdk15on:1.61 org.bouncycastle:bcprov-jdk15on:1.61 org.checkerframework:checker-qual:2.5.2 diff --git a/proxy/src/main/java/google/registry/proxy/MetricsModule.java b/proxy/src/main/java/google/registry/proxy/MetricsModule.java index db8fb7094..747bdccae 100644 --- a/proxy/src/main/java/google/registry/proxy/MetricsModule.java +++ b/proxy/src/main/java/google/registry/proxy/MetricsModule.java @@ -14,8 +14,6 @@ package google.registry.proxy; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; -import com.google.api.client.googleapis.util.Utils; import com.google.api.services.monitoring.v3.Monitoring; import com.google.api.services.monitoring.v3.model.MonitoredResource; import com.google.common.collect.ImmutableMap; @@ -29,6 +27,7 @@ import dagger.Module; import dagger.Provides; import google.registry.proxy.ProxyConfig.Environment; import google.registry.proxy.metric.MetricParameters; +import google.registry.util.GoogleCredentialsBundle; import javax.inject.Singleton; /** Module that provides necessary bindings to instantiate a {@link MetricReporter} */ @@ -39,9 +38,12 @@ public class MetricsModule { @Singleton @Provides - static Monitoring provideMonitoring(GoogleCredential credential, ProxyConfig config) { + static Monitoring provideMonitoring(GoogleCredentialsBundle credentialsBundle, + ProxyConfig config) { return new Monitoring.Builder( - Utils.getDefaultTransport(), Utils.getDefaultJsonFactory(), credential) + credentialsBundle.getHttpTransport(), + credentialsBundle.getJsonFactory(), + credentialsBundle.getHttpRequestInitializer()) .setApplicationName(config.projectId) .build(); } diff --git a/proxy/src/main/java/google/registry/proxy/ProxyModule.java b/proxy/src/main/java/google/registry/proxy/ProxyModule.java index c859ce2c8..8bc02a7c7 100644 --- a/proxy/src/main/java/google/registry/proxy/ProxyModule.java +++ b/proxy/src/main/java/google/registry/proxy/ProxyModule.java @@ -20,11 +20,11 @@ import static google.registry.proxy.ProxyConfig.getProxyConfig; import com.beust.jcommander.JCommander; import com.beust.jcommander.Parameter; import com.beust.jcommander.ParameterException; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; -import com.google.api.client.googleapis.util.Utils; import com.google.api.services.cloudkms.v1.CloudKMS; import com.google.api.services.cloudkms.v1.model.DecryptRequest; import com.google.api.services.storage.Storage; +import com.google.auth.oauth2.AccessToken; +import com.google.auth.oauth2.GoogleCredentials; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import com.google.common.flogger.LoggerConfig; @@ -41,6 +41,7 @@ import google.registry.proxy.WebWhoisProtocolsModule.HttpsWhoisProtocol; import google.registry.proxy.WhoisProtocolModule.WhoisProtocol; import google.registry.proxy.handler.ProxyProtocolHandler; import google.registry.util.Clock; +import google.registry.util.GoogleCredentialsBundle; import google.registry.util.SystemClock; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; @@ -50,6 +51,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.Base64; +import java.util.Date; import java.util.Optional; import java.util.Set; import java.util.concurrent.ExecutorService; @@ -209,13 +211,13 @@ public class ProxyModule { @Singleton @Provides - static GoogleCredential provideCredential(ProxyConfig config) { + static GoogleCredentialsBundle provideCredential(ProxyConfig config) { try { - GoogleCredential credential = GoogleCredential.getApplicationDefault(); - if (credential.createScopedRequired()) { - credential = credential.createScoped(config.gcpScopes); + GoogleCredentials credentials = GoogleCredentials.getApplicationDefault(); + if (credentials.createScopedRequired()) { + credentials = credentials.createScoped(config.gcpScopes); } - return credential; + return GoogleCredentialsBundle.create(credentials); } catch (IOException e) { throw new RuntimeException("Unable to obtain OAuth2 credential.", e); } @@ -226,36 +228,45 @@ public class ProxyModule { @Provides @Named("accessToken") static Supplier provideAccessTokenSupplier( - GoogleCredential credential, ProxyConfig config) { + GoogleCredentialsBundle credentialsBundle, ProxyConfig config) { return () -> { + GoogleCredentials credentials = credentialsBundle.getGoogleCredentials(); + AccessToken accessToken = credentials.getAccessToken(); + Date nextExpirationTime = + new Date( + System.currentTimeMillis() + config.accessTokenRefreshBeforeExpirationSeconds * 1000); // If we never obtained an access token, the expiration time is null. - if (credential.getExpiresInSeconds() == null + if (accessToken == null // If we have an access token, make sure to refresh it ahead of time. - || credential.getExpiresInSeconds() < config.accessTokenRefreshBeforeExpirationSeconds) { + || accessToken.getExpirationTime().before(nextExpirationTime)) { try { - credential.refreshToken(); + credentials.refresh(); } catch (IOException e) { throw new RuntimeException("Cannot refresh access token.", e); } } - return credential.getAccessToken(); + return credentials.getAccessToken().getTokenValue(); }; } @Singleton @Provides - static CloudKMS provideCloudKms(GoogleCredential credential, ProxyConfig config) { + static CloudKMS provideCloudKms(GoogleCredentialsBundle credentialsBundle, ProxyConfig config) { return new CloudKMS.Builder( - Utils.getDefaultTransport(), Utils.getDefaultJsonFactory(), credential) + credentialsBundle.getHttpTransport(), + credentialsBundle.getJsonFactory(), + credentialsBundle.getHttpRequestInitializer()) .setApplicationName(config.projectId) .build(); } @Singleton @Provides - static Storage provideStorage(GoogleCredential credential, ProxyConfig config) { + static Storage provideStorage(GoogleCredentialsBundle credentialsBundle, ProxyConfig config) { return new Storage.Builder( - Utils.getDefaultTransport(), Utils.getDefaultJsonFactory(), credential) + credentialsBundle.getHttpTransport(), + credentialsBundle.getJsonFactory(), + credentialsBundle.getHttpRequestInitializer()) .setApplicationName(config.projectId) .build(); } @@ -337,14 +348,14 @@ public class ProxyModule { @Singleton @Component( modules = { - ProxyModule.class, - CertificateModule.class, - HttpsRelayProtocolModule.class, - WhoisProtocolModule.class, - WebWhoisProtocolsModule.class, - EppProtocolModule.class, - HealthCheckProtocolModule.class, - MetricsModule.class + ProxyModule.class, + CertificateModule.class, + HttpsRelayProtocolModule.class, + WhoisProtocolModule.class, + WebWhoisProtocolsModule.class, + EppProtocolModule.class, + HealthCheckProtocolModule.class, + MetricsModule.class }) interface ProxyComponent { diff --git a/util/build.gradle b/util/build.gradle index 28a39dd5d..b7a32ef25 100644 --- a/util/build.gradle +++ b/util/build.gradle @@ -2,8 +2,11 @@ apply plugin: 'java' dependencies { def deps = rootProject.dependencyMap + compile deps['com.google.api-client:google-api-client'] compile deps['com.google.appengine:appengine-api-1.0-sdk'] compile deps['com.google.appengine:appengine-testing'] + compile deps['com.google.auth:google-auth-library-credentials'] + compile deps['com.google.auth:google-auth-library-oauth2-http'] compile deps['com.google.auto.value:auto-value-annotations'] compile deps['com.google.code.findbugs:jsr305'] compile deps['com.google.dagger:dagger'] diff --git a/util/gradle/dependency-locks/compile.lockfile b/util/gradle/dependency-locks/compile.lockfile index 1e47c8961..08a9b227a 100644 --- a/util/gradle/dependency-locks/compile.lockfile +++ b/util/gradle/dependency-locks/compile.lockfile @@ -1,8 +1,12 @@ # 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. +com.fasterxml.jackson.core:jackson-core:2.9.9 +com.google.api-client:google-api-client:1.29.2 com.google.appengine:appengine-api-1.0-sdk:1.9.48 com.google.appengine:appengine-testing:1.9.58 +com.google.auth:google-auth-library-credentials:0.16.1 +com.google.auth:google-auth-library-oauth2-http:0.16.1 com.google.auto.value:auto-value-annotations:1.6.3 com.google.code.findbugs:jsr305:3.0.2 com.google.dagger:dagger:2.21 @@ -11,14 +15,24 @@ com.google.flogger:flogger:0.1 com.google.guava:failureaccess:1.0.1 com.google.guava:guava:27.1-jre com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava -com.google.j2objc:j2objc-annotations:1.1 +com.google.http-client:google-http-client-jackson2:1.30.1 +com.google.http-client:google-http-client:1.30.1 +com.google.j2objc:j2objc-annotations:1.3 +com.google.oauth-client:google-oauth-client:1.29.2 com.google.re2j:re2j:1.1 com.ibm.icu:icu4j:57.1 +commons-codec:commons-codec:1.11 +commons-logging:commons-logging:1.2 +io.grpc:grpc-context:1.19.0 +io.opencensus:opencensus-api:0.21.0 +io.opencensus:opencensus-contrib-http-util:0.21.0 javax.activation:activation:1.1 javax.inject:javax.inject:1 javax.mail:mail:1.4 javax.xml.bind:jaxb-api:2.3.0 joda-time:joda-time:2.9.2 +org.apache.httpcomponents:httpclient:4.5.8 +org.apache.httpcomponents:httpcore:4.4.11 org.checkerframework:checker-qual:2.5.2 org.codehaus.mojo:animal-sniffer-annotations:1.17 org.yaml:snakeyaml:1.17 diff --git a/util/gradle/dependency-locks/compileClasspath.lockfile b/util/gradle/dependency-locks/compileClasspath.lockfile index 1e47c8961..08a9b227a 100644 --- a/util/gradle/dependency-locks/compileClasspath.lockfile +++ b/util/gradle/dependency-locks/compileClasspath.lockfile @@ -1,8 +1,12 @@ # 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. +com.fasterxml.jackson.core:jackson-core:2.9.9 +com.google.api-client:google-api-client:1.29.2 com.google.appengine:appengine-api-1.0-sdk:1.9.48 com.google.appengine:appengine-testing:1.9.58 +com.google.auth:google-auth-library-credentials:0.16.1 +com.google.auth:google-auth-library-oauth2-http:0.16.1 com.google.auto.value:auto-value-annotations:1.6.3 com.google.code.findbugs:jsr305:3.0.2 com.google.dagger:dagger:2.21 @@ -11,14 +15,24 @@ com.google.flogger:flogger:0.1 com.google.guava:failureaccess:1.0.1 com.google.guava:guava:27.1-jre com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava -com.google.j2objc:j2objc-annotations:1.1 +com.google.http-client:google-http-client-jackson2:1.30.1 +com.google.http-client:google-http-client:1.30.1 +com.google.j2objc:j2objc-annotations:1.3 +com.google.oauth-client:google-oauth-client:1.29.2 com.google.re2j:re2j:1.1 com.ibm.icu:icu4j:57.1 +commons-codec:commons-codec:1.11 +commons-logging:commons-logging:1.2 +io.grpc:grpc-context:1.19.0 +io.opencensus:opencensus-api:0.21.0 +io.opencensus:opencensus-contrib-http-util:0.21.0 javax.activation:activation:1.1 javax.inject:javax.inject:1 javax.mail:mail:1.4 javax.xml.bind:jaxb-api:2.3.0 joda-time:joda-time:2.9.2 +org.apache.httpcomponents:httpclient:4.5.8 +org.apache.httpcomponents:httpcore:4.4.11 org.checkerframework:checker-qual:2.5.2 org.codehaus.mojo:animal-sniffer-annotations:1.17 org.yaml:snakeyaml:1.17 diff --git a/util/gradle/dependency-locks/runtimeClasspath.lockfile b/util/gradle/dependency-locks/runtimeClasspath.lockfile index c2853cbbe..4578e4162 100644 --- a/util/gradle/dependency-locks/runtimeClasspath.lockfile +++ b/util/gradle/dependency-locks/runtimeClasspath.lockfile @@ -1,8 +1,12 @@ # 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. +com.fasterxml.jackson.core:jackson-core:2.9.9 +com.google.api-client:google-api-client:1.29.2 com.google.appengine:appengine-api-1.0-sdk:1.9.48 com.google.appengine:appengine-testing:1.9.58 +com.google.auth:google-auth-library-credentials:0.16.1 +com.google.auth:google-auth-library-oauth2-http:0.16.1 com.google.auto.value:auto-value-annotations:1.6.3 com.google.auto.value:auto-value:1.6.3 com.google.code.findbugs:jsr305:3.0.2 @@ -12,14 +16,24 @@ com.google.flogger:flogger:0.1 com.google.guava:failureaccess:1.0.1 com.google.guava:guava:27.1-jre com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava -com.google.j2objc:j2objc-annotations:1.1 +com.google.http-client:google-http-client-jackson2:1.30.1 +com.google.http-client:google-http-client:1.30.1 +com.google.j2objc:j2objc-annotations:1.3 +com.google.oauth-client:google-oauth-client:1.29.2 com.google.re2j:re2j:1.1 com.ibm.icu:icu4j:57.1 +commons-codec:commons-codec:1.11 +commons-logging:commons-logging:1.2 +io.grpc:grpc-context:1.19.0 +io.opencensus:opencensus-api:0.21.0 +io.opencensus:opencensus-contrib-http-util:0.21.0 javax.activation:activation:1.1 javax.inject:javax.inject:1 javax.mail:mail:1.4 javax.xml.bind:jaxb-api:2.3.0 joda-time:joda-time:2.9.2 +org.apache.httpcomponents:httpclient:4.5.8 +org.apache.httpcomponents:httpcore:4.4.11 org.checkerframework:checker-qual:2.5.2 org.codehaus.mojo:animal-sniffer-annotations:1.17 org.yaml:snakeyaml:1.17 diff --git a/util/src/main/java/google/registry/util/GoogleCredentialsBundle.java b/util/src/main/java/google/registry/util/GoogleCredentialsBundle.java new file mode 100644 index 000000000..b42fb13f5 --- /dev/null +++ b/util/src/main/java/google/registry/util/GoogleCredentialsBundle.java @@ -0,0 +1,70 @@ +// Copyright 2019 The Nomulus Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package google.registry.util; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.api.client.googleapis.util.Utils; +import com.google.api.client.http.HttpRequestInitializer; +import com.google.api.client.http.HttpTransport; +import com.google.api.client.json.JsonFactory; +import com.google.auth.http.HttpCredentialsAdapter; +import com.google.auth.oauth2.GoogleCredentials; + +/** + * Helper class to provide {@link HttpTransport}, {@link JsonFactory} and {@link + * HttpRequestInitializer} for a given {@link GoogleCredentials}. These classes are normally needed + * for creating the instance of a GCP client. + */ +public class GoogleCredentialsBundle { + + private GoogleCredentials googleCredentials; + private HttpTransport httpTransport; + private JsonFactory jsonFactory; + private HttpRequestInitializer httpRequestInitializer; + + private GoogleCredentialsBundle(GoogleCredentials googleCredentials) { + checkNotNull(googleCredentials); + this.googleCredentials = googleCredentials; + this.httpTransport = Utils.getDefaultTransport(); + this.jsonFactory = Utils.getDefaultJsonFactory(); + this.httpRequestInitializer = new HttpCredentialsAdapter(googleCredentials); + } + + /** Creates a {@link GoogleCredentialsBundle} instance from given {@link GoogleCredentials}. */ + public static GoogleCredentialsBundle create(GoogleCredentials credentials) { + return new GoogleCredentialsBundle(credentials); + } + + /** Returns the same {@link GoogleCredentials} used to create this object. */ + public GoogleCredentials getGoogleCredentials() { + return googleCredentials; + } + + /** Returns the instance of {@link HttpTransport}. */ + public HttpTransport getHttpTransport() { + return httpTransport; + } + + /** Returns the instance of {@link JsonFactory}. */ + public JsonFactory getJsonFactory() { + return jsonFactory; + } + + /** Returns the instance of {@link HttpRequestInitializer}. */ + public HttpRequestInitializer getHttpRequestInitializer() { + return httpRequestInitializer; + } +}