google-nomulus/java/google/registry/request/Modules.java
Michael Muller c458c05801 Rename Java packages to use the .google TLD
The dark lord Gosling designed the Java package naming system so that
ownership flows from the DNS system. Since we own the domain name
registry.google, it seems only appropriate that we should use
google.registry as our package name.
2016-05-13 20:04:42 -04:00

203 lines
7.1 KiB
Java

// Copyright 2016 The Domain Registry 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.request;
import static com.google.appengine.api.datastore.DatastoreServiceFactory.getDatastoreService;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.api.client.extensions.appengine.http.UrlFetchTransport;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.extensions.appengine.auth.oauth2.AppIdentityCredential;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.modules.ModulesService;
import com.google.appengine.api.modules.ModulesServiceFactory;
import com.google.appengine.api.urlfetch.URLFetchService;
import com.google.appengine.api.urlfetch.URLFetchServiceFactory;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import dagger.Module;
import dagger.Provides;
import google.registry.config.ConfigModule.Config;
import google.registry.keyring.api.KeyModule.Key;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Set;
import javax.inject.Named;
import javax.inject.Singleton;
/** Dagger modules for App Engine services and other vendor classes. */
public final class Modules {
/** Dagger module for {@link DatastoreService}. */
@Module
public static final class DatastoreServiceModule {
private static final DatastoreService datastoreService = getDatastoreService();
@Provides
static DatastoreService provideDatastoreService() {
return datastoreService;
}
}
/** Dagger module for {@link ModulesService}. */
@Module
public static final class ModulesServiceModule {
private static final ModulesService modulesService = ModulesServiceFactory.getModulesService();
@Provides
static ModulesService provideModulesService() {
return modulesService;
}
}
/** Dagger module for {@link URLFetchService}. */
@Module
public static final class URLFetchServiceModule {
private static final URLFetchService fetchService = URLFetchServiceFactory.getURLFetchService();
@Provides
static URLFetchService provideURLFetchService() {
return fetchService;
}
}
/** Dagger module for {@link UserService}. */
@Module
public static final class UserServiceModule {
private static final UserService userService = UserServiceFactory.getUserService();
@Provides
static UserService provideUserService() {
return userService;
}
}
/**
* Dagger module that causes the Jackson2 JSON parser to be used for Google APIs requests.
*
* <p>Jackson1 and GSON can also satisfy the {@link JsonFactory} interface, but we've decided to
* go with Jackson2, since it's what's used in the public examples for using Google APIs.
*/
@Module
public static final class Jackson2Module {
@Provides
static JsonFactory provideJsonFactory() {
return JacksonFactory.getDefaultInstance();
}
}
/** Dagger module that causes the App Engine's URL fetcher to be used for Google APIs requests. */
@Module
public static final class UrlFetchTransportModule {
private static final UrlFetchTransport HTTP_TRANSPORT = new UrlFetchTransport();
@Provides
static HttpTransport provideHttpTransport() {
return HTTP_TRANSPORT;
}
}
/**
* Dagger module providing {@link AppIdentityCredential}.
*
* <p>This can be used to authenticate to Google APIs using the identity of your GAE app.
*
* @see UseAppIdentityCredentialForGoogleApisModule
*/
@Module
public static final class AppIdentityCredentialModule {
@Provides
static AppIdentityCredential provideAppIdentityCredential(@OAuthScopes Set<String> scopes) {
return new AppIdentityCredential(scopes);
}
}
/**
* Dagger module causing Google APIs requests to be authorized with your GAE app identity.
*
* <p>You must also use the {@link AppIdentityCredential} module.
*/
@Module
public static final class UseAppIdentityCredentialForGoogleApisModule {
@Provides
static HttpRequestInitializer provideHttpRequestInitializer(AppIdentityCredential credential) {
return credential;
}
}
/**
* Dagger module providing {@link GoogleCredential} from a JSON key file contents.
*
* <p>This satisfies the {@link HttpRequestInitializer} interface for authenticating Google APIs
* requests, just like {@link AppIdentityCredential}.
*
* <p>But we consider GAE authentication more desirable and easier to manage operations-wise. So
* this authentication method should only be used for the following situations:
*
* <ol>
* <li>Locally-running programs (which aren't executing on the App Engine platform)
* <li>Spreadsheet service (which can't use {@link AppIdentityCredential} due to an old library)
* </ol>
*
* @see google.registry.keyring.api.Keyring#getJsonCredential()
*/
@Module
public static final class GoogleCredentialModule {
@Provides
static GoogleCredential provideGoogleCredential(
HttpTransport httpTransport,
JsonFactory jsonFactory,
@Key("jsonCredential") String jsonCredential) {
try {
return GoogleCredential.fromStream(
new ByteArrayInputStream(jsonCredential.getBytes(UTF_8)), httpTransport, jsonFactory);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* Provides a GoogleCredential that will connect to GAE using delegated admin access. This is
* needed for API calls requiring domain admin access to the relevant GAFYD using delegated
* scopes, e.g. the Directory API and the Groupssettings API.
*/
@Provides
@Singleton
@Named("delegatedAdmin")
static GoogleCredential provideDelegatedAdminGoogleCredential(
GoogleCredential googleCredential,
HttpTransport httpTransport,
@DelegatedOAuthScopes Set<String> scopes,
@Config("googleAppsAdminEmailAddress") String googleAppsAdminEmailAddress) {
return new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(googleCredential.getJsonFactory())
.setServiceAccountId(googleCredential.getServiceAccountId())
.setServiceAccountPrivateKey(googleCredential.getServiceAccountPrivateKey())
.setServiceAccountScopes(scopes)
.setServiceAccountUser(googleAppsAdminEmailAddress)
.build();
}
}
}