use of org.dataportabilityproject.spi.cloud.types.PortabilityJob in project data-transfer-project by google.
the class LocalJobStore method updateJob.
/**
* Verifies a {@code PortabilityJob} already exists for {@code jobId}, and updates the entry to
* {@code job}. If {@code validator} is non-null, validator.validate() is called first, as part of
* the atomic update.
*
* @throws IOException if a job didn't already exist for {@code jobId} or there was a problem
* updating it
* @throws IllegalStateException if validator.validate() failed
*/
@Override
public synchronized void updateJob(UUID jobId, PortabilityJob job, JobUpdateValidator validator) throws IOException {
Preconditions.checkNotNull(jobId);
try {
Map<String, Object> previousEntry = JOB_MAP.replace(jobId, job.toMap());
if (previousEntry == null) {
throw new IOException("jobId: " + jobId + " didn't exist in the map");
}
if (validator != null) {
PortabilityJob previousJob = PortabilityJob.fromMap(previousEntry);
validator.validate(previousJob, job);
}
} catch (NullPointerException | IllegalStateException e) {
throw new IOException("Couldn't update jobId: " + jobId, e);
}
}
use of org.dataportabilityproject.spi.cloud.types.PortabilityJob in project data-transfer-project by google.
the class OauthCallbackHandler method handleExchange.
private String handleExchange(HttpExchange exchange) throws IOException {
String redirect = "/error";
try {
Headers requestHeaders = exchange.getRequestHeaders();
// Get the URL for the request - needed for the authorization.
String requestURL = ReferenceApiUtils.createURL(requestHeaders.getFirst(HttpHeaders.HOST), exchange.getRequestURI().toString(), IS_LOCAL);
Map<String, String> requestParams = ReferenceApiUtils.getRequestParams(exchange);
String encodedIdCookie = ReferenceApiUtils.getCookie(requestHeaders, JsonKeys.ID_COOKIE_KEY);
Preconditions.checkArgument(!Strings.isNullOrEmpty(encodedIdCookie), "Missing encodedIdCookie");
String oauthToken = requestParams.get("oauth_token");
Preconditions.checkArgument(!Strings.isNullOrEmpty(oauthToken), "Missing oauth_token");
String oauthVerifier = requestParams.get("oauth_verifier");
Preconditions.checkArgument(!Strings.isNullOrEmpty(oauthVerifier), "Missing oauth_verifier");
// Valid job must be present
Preconditions.checkArgument(!Strings.isNullOrEmpty(encodedIdCookie), "Encoded Id cookie required");
UUID jobId = ReferenceApiUtils.decodeJobId(encodedIdCookie);
PortabilityJob job = store.findJob(jobId);
logger.debug("Found job: {}->{} in OCH", jobId, job);
Preconditions.checkNotNull(job, "existing job not found for jobId: %s", jobId);
// TODO: Determine service from job or from authUrl path?
AuthMode authMode = ReferenceApiUtils.getAuthMode(exchange.getRequestHeaders());
String service = (authMode == AuthMode.EXPORT) ? job.exportService() : job.importService();
Preconditions.checkState(!Strings.isNullOrEmpty(service), "service not found, service: %s authMode: %s, jobId: %s", service, authMode, jobId.toString());
AuthDataGenerator generator = registry.getAuthDataGenerator(service, job.transferDataType(), authMode);
Preconditions.checkNotNull(generator, "Generator not found for type: %s, service: %s", job.transferDataType(), service);
// Obtain the session key for this job
String encodedSessionKey = job.jobAuthorization().sessionSecretKey();
SecretKey key = symmetricKeyGenerator.parse(BaseEncoding.base64Url().decode(encodedSessionKey));
// Retrieve initial auth data, if it existed
AuthData initialAuthData = null;
String encryptedInitialAuthData = (authMode == AuthMode.EXPORT) ? job.jobAuthorization().encryptedInitialExportAuthData() : job.jobAuthorization().encryptedInitialImportAuthData();
if (encryptedInitialAuthData != null) {
// Retrieve and parse the session key from the job
// Decrypt and deserialize the object
String serialized = DecrypterFactory.create(key).decrypt(encryptedInitialAuthData);
initialAuthData = objectMapper.readValue(serialized, AuthData.class);
}
Preconditions.checkNotNull(initialAuthData, "Initial AuthData expected during Oauth 1.0 flow");
// TODO: Use UUID instead of UUID.toString()
// Generate auth data
AuthData authData = generator.generateAuthData(baseApiUrl, oauthVerifier, jobId.toString(), initialAuthData, null);
Preconditions.checkNotNull(authData, "Auth data should not be null");
// Serialize and encrypt the auth data
String serialized = objectMapper.writeValueAsString(authData);
String encryptedAuthData = EncrypterFactory.create(key).encrypt(serialized);
// Set new cookie
ReferenceApiUtils.setCookie(exchange.getResponseHeaders(), encryptedAuthData, authMode);
redirect = baseUrl + ((authMode == AuthMode.EXPORT) ? FrontendConstantUrls.URL_NEXT_PAGE : FrontendConstantUrls.URL_COPY_PAGE);
} catch (Exception e) {
logger.error("Error handling request", e);
throw e;
}
return redirect;
}
use of org.dataportabilityproject.spi.cloud.types.PortabilityJob in project data-transfer-project by google.
the class SetupHandler method handle.
@Override
public void handle(HttpExchange exchange) throws IOException {
try {
logger.debug("Entering setup handler, exchange: {}", exchange);
Preconditions.checkArgument(ReferenceApiUtils.validateRequest(exchange, HttpMethods.GET, handlerUrlPath));
String encodedIdCookie = ReferenceApiUtils.getCookie(exchange.getRequestHeaders(), JsonKeys.ID_COOKIE_KEY);
Preconditions.checkArgument(!Strings.isNullOrEmpty(encodedIdCookie), "Encoded Id cookie required");
// Valid job must be present
UUID jobId = ReferenceApiUtils.decodeJobId(encodedIdCookie);
PortabilityJob job = store.findJob(jobId);
Preconditions.checkNotNull(job, "existing job not found for jobId: %s", jobId);
// This page is only valid after the oauth of the export service - export data should exist
// for all setup Modes.
String exportService = job.exportService();
Preconditions.checkState(!Strings.isNullOrEmpty(exportService), "Export service is invalid");
String importService = job.importService();
Preconditions.checkState(!Strings.isNullOrEmpty(importService), "Import service is invalid");
DataTransferResponse response;
if (mode == Mode.IMPORT) {
response = handleImportSetup(exchange.getRequestHeaders(), job, jobId);
} else {
response = handleCopySetup(exchange.getRequestHeaders(), job, jobId);
// Valid job is present, generate an XSRF token to pass back via cookie
String tokenStr = tokenManager.createNewToken(jobId);
HttpCookie token = new HttpCookie(JsonKeys.XSRF_TOKEN, tokenStr);
exchange.getResponseHeaders().add(HttpHeaders.SET_COOKIE, token.toString() + ReferenceApiUtils.COOKIE_ATTRIBUTES);
}
// Mark the response as type Json and send
exchange.getResponseHeaders().set(CONTENT_TYPE, "application/json; charset=" + StandardCharsets.UTF_8.name());
exchange.sendResponseHeaders(200, 0);
objectMapper.writeValue(exchange.getResponseBody(), response);
} catch (Exception e) {
logger.error("Error handling request", e);
throw e;
}
}
use of org.dataportabilityproject.spi.cloud.types.PortabilityJob in project data-transfer-project by google.
the class SimpleLoginSubmitHandler method handleExchange.
DataTransferResponse handleExchange(HttpExchange exchange) throws IOException {
Headers requestHeaders = exchange.getRequestHeaders();
try {
SimpleLoginRequest request = objectMapper.readValue(exchange.getRequestBody(), SimpleLoginRequest.class);
String encodedIdCookie = ReferenceApiUtils.getCookie(requestHeaders, JsonKeys.ID_COOKIE_KEY);
Preconditions.checkArgument(!Strings.isNullOrEmpty(encodedIdCookie), "Missing encodedIdCookie");
// Valid job must be present
Preconditions.checkArgument(!Strings.isNullOrEmpty(encodedIdCookie), "Encoded Id cookie required");
UUID jobId = ReferenceApiUtils.decodeJobId(encodedIdCookie);
PortabilityJob job = store.findJob(jobId);
Preconditions.checkNotNull(job, "existing job not found for jobId: %s", jobId);
// TODO: Determine service from job or from authUrl path?
AuthMode authMode = ReferenceApiUtils.getAuthMode(exchange.getRequestHeaders());
// TODO: Determine service from job or from authUrl path?
String service = (authMode == AuthMode.EXPORT) ? job.exportService() : job.importService();
Preconditions.checkState(!Strings.isNullOrEmpty(service), "service not found, service: %s authMode: %s, jobId: %s", service, authMode, jobId);
Preconditions.checkArgument(!Strings.isNullOrEmpty(request.getUsername()), "Missing valid username");
Preconditions.checkArgument(!Strings.isNullOrEmpty(request.getPassword()), "Missing password");
AuthDataGenerator generator = registry.getAuthDataGenerator(service, job.transferDataType(), AuthMode.EXPORT);
Preconditions.checkNotNull(generator, "Generator not found for type: %s, service: %s", job.transferDataType(), service);
// TODO: change signature to pass UUID
// Generate and store auth data
AuthData authData = generator.generateAuthData(baseApiUrl, request.getUsername(), jobId.toString(), null, request.getPassword());
Preconditions.checkNotNull(authData, "Auth data should not be null");
// Obtain the session key for this job
String encodedSessionKey = job.jobAuthorization().sessionSecretKey();
SecretKey key = symmetricKeyGenerator.parse(BaseEncoding.base64Url().decode(encodedSessionKey));
// Serialize and encrypt the auth data
String serialized = objectMapper.writeValueAsString(authData);
String encryptedAuthData = EncrypterFactory.create(key).encrypt(serialized);
// Set new cookie
ReferenceApiUtils.setCookie(exchange.getResponseHeaders(), encryptedAuthData, authMode);
return new DataTransferResponse(job.exportService(), job.importService(), job.transferDataType(), Status.INPROCESS, baseUrl + (authMode == AuthMode.EXPORT ? FrontendConstantUrls.URL_NEXT_PAGE : FrontendConstantUrls.URL_COPY_PAGE));
} catch (Exception e) {
logger.debug("Exception occurred while trying to handle request: {}", e);
throw e;
}
}
use of org.dataportabilityproject.spi.cloud.types.PortabilityJob in project data-transfer-project by google.
the class JobPollingService method claimJob.
/**
* Claims {@link PortabilityJob} {@code jobId} and updates it with our public key in storage.
*/
private void claimJob(UUID jobId, KeyPair keyPair) throws IOException {
// Lookup the job so we can append to its existing properties.
PortabilityJob existingJob = store.findJob(jobId);
// Verify no worker key
if (existingJob.jobAuthorization().authPublicKey() != null) {
throw new IOException("public key cannot be persisted again");
}
// Populate job with public key to persist
String encodedPublicKey = BaseEncoding.base64Url().encode(keyPair.getPublic().getEncoded());
PortabilityJob updatedJob = existingJob.toBuilder().setAndValidateJobAuthorization(existingJob.jobAuthorization().toBuilder().setAuthPublicKey(encodedPublicKey).setState(JobAuthorization.State.CREDS_ENCRYPTION_KEY_GENERATED).build()).build();
// to CREDS_ENCRYPTION_KEY_GENERATED.
try {
store.updateJob(jobId, updatedJob, (previous, updated) -> Preconditions.checkState(previous.jobAuthorization().state() == JobAuthorization.State.CREDS_AVAILABLE));
} catch (IllegalStateException e) {
throw new IOException("Could not 'claim' job " + jobId + ". It was probably already " + "claimed by another worker", e);
}
JobMetadata.init(jobId, keyPair, existingJob.transferDataType(), existingJob.exportService(), existingJob.importService());
}
Aggregations