Search in sources :

Example 1 with PortabilityJob

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);
    }
}
Also used : PortabilityJob(org.dataportabilityproject.spi.cloud.types.PortabilityJob) IOException(java.io.IOException)

Example 2 with PortabilityJob

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;
}
Also used : PortabilityJob(org.dataportabilityproject.spi.cloud.types.PortabilityJob) AuthDataGenerator(org.dataportabilityproject.spi.gateway.auth.AuthDataGenerator) SecretKey(javax.crypto.SecretKey) AuthData(org.dataportabilityproject.types.transfer.auth.AuthData) HttpHeaders(com.google.common.net.HttpHeaders) Headers(com.sun.net.httpserver.Headers) UUID(java.util.UUID) AuthMode(org.dataportabilityproject.spi.gateway.auth.AuthServiceProviderRegistry.AuthMode) IOException(java.io.IOException)

Example 3 with PortabilityJob

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;
    }
}
Also used : PortabilityJob(org.dataportabilityproject.spi.cloud.types.PortabilityJob) DataTransferResponse(org.dataportabilityproject.types.client.transfer.DataTransferResponse) UUID(java.util.UUID) HttpCookie(java.net.HttpCookie) IOException(java.io.IOException)

Example 4 with PortabilityJob

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;
    }
}
Also used : PortabilityJob(org.dataportabilityproject.spi.cloud.types.PortabilityJob) AuthDataGenerator(org.dataportabilityproject.spi.gateway.auth.AuthDataGenerator) SecretKey(javax.crypto.SecretKey) AuthData(org.dataportabilityproject.types.transfer.auth.AuthData) Headers(com.sun.net.httpserver.Headers) HttpHeaders(org.apache.http.HttpHeaders) SimpleLoginRequest(org.dataportabilityproject.types.client.transfer.SimpleLoginRequest) DataTransferResponse(org.dataportabilityproject.types.client.transfer.DataTransferResponse) UUID(java.util.UUID) AuthMode(org.dataportabilityproject.spi.gateway.auth.AuthServiceProviderRegistry.AuthMode) IOException(java.io.IOException)

Example 5 with PortabilityJob

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());
}
Also used : PortabilityJob(org.dataportabilityproject.spi.cloud.types.PortabilityJob) IOException(java.io.IOException)

Aggregations

PortabilityJob (org.dataportabilityproject.spi.cloud.types.PortabilityJob)17 IOException (java.io.IOException)10 UUID (java.util.UUID)8 SecretKey (javax.crypto.SecretKey)7 JobAuthorization (org.dataportabilityproject.spi.cloud.types.JobAuthorization)6 AuthDataGenerator (org.dataportabilityproject.spi.gateway.auth.AuthDataGenerator)5 DataTransferResponse (org.dataportabilityproject.types.client.transfer.DataTransferResponse)4 AuthData (org.dataportabilityproject.types.transfer.auth.AuthData)4 Headers (com.sun.net.httpserver.Headers)3 HttpCookie (java.net.HttpCookie)3 AuthMode (org.dataportabilityproject.spi.gateway.auth.AuthServiceProviderRegistry.AuthMode)3 HttpHeaders (com.google.common.net.HttpHeaders)2 AuthFlowConfiguration (org.dataportabilityproject.spi.gateway.types.AuthFlowConfiguration)2 Test (org.junit.Test)2 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 AuthorizationCodeResponseUrl (com.google.api.client.auth.oauth2.AuthorizationCodeResponseUrl)1 Entity (com.google.cloud.datastore.Entity)1 Key (com.google.cloud.datastore.Key)1 Transaction (com.google.cloud.datastore.Transaction)1 Map (java.util.Map)1