Search in sources :

Example 1 with RestMethod

use of com.github.ambry.rest.RestMethod in project ambry by linkedin.

the class AmbryUrlSigningService method verifySignedRequest.

@Override
public void verifySignedRequest(RestRequest restRequest) throws RestServiceException {
    if (!isRequestSigned(restRequest)) {
        throw new RestServiceException("Request is not signed - method should not have been called", RestServiceErrorCode.InternalServerError);
    }
    Map<String, Object> args = restRequest.getArgs();
    long expiryTimeSecs = RestUtils.getLongHeader(args, LINK_EXPIRY_TIME, true);
    if (time.seconds() > expiryTimeSecs) {
        throw new RestServiceException("Signed URL has expired", RestServiceErrorCode.Unauthorized);
    }
    RestMethod restMethodInUrl = RestMethod.valueOf(RestUtils.getHeader(args, RestUtils.Headers.URL_TYPE, true));
    if (!restRequest.getRestMethod().equals(restMethodInUrl)) {
        throw new RestServiceException("Type of request being made not compatible with signed URL", RestServiceErrorCode.Unauthorized);
    }
}
Also used : RestServiceException(com.github.ambry.rest.RestServiceException) RestMethod(com.github.ambry.rest.RestMethod)

Example 2 with RestMethod

use of com.github.ambry.rest.RestMethod in project ambry by linkedin.

the class AmbryUrlSigningService method getSignedUrl.

@Override
public String getSignedUrl(RestRequest restRequest) throws RestServiceException {
    Map<String, Object> args = restRequest.getArgs();
    String restMethodInSignedUrlStr = RestUtils.getHeader(args, RestUtils.Headers.URL_TYPE, true);
    RestMethod restMethodInSignedUrl;
    try {
        restMethodInSignedUrl = RestMethod.valueOf(restMethodInSignedUrlStr);
    } catch (IllegalArgumentException e) {
        throw new RestServiceException("Unrecognized RestMethod: " + restMethodInSignedUrlStr, RestServiceErrorCode.InvalidArgs);
    }
    StringBuilder urlBuilder = new StringBuilder();
    switch(restMethodInSignedUrl) {
        case GET:
            urlBuilder.append(downloadEndpoint).append(QUERY_STRING_START);
            break;
        case POST:
            urlBuilder.append(uploadEndpoint).append(QUERY_STRING_START);
            break;
        default:
            throw new RestServiceException("Signing request for " + restMethodInSignedUrl + " is not supported", RestServiceErrorCode.InvalidArgs);
    }
    long urlTtlSecs = defaultUrlTtlSecs;
    long maxUploadSize = defaultMaxUploadSize;
    for (Map.Entry<String, Object> entry : args.entrySet()) {
        String name = entry.getKey();
        Object value = entry.getValue();
        if (name.regionMatches(true, 0, AMBRY_PARAMETERS_PREFIX, 0, AMBRY_PARAMETERS_PREFIX.length()) && value instanceof String) {
            switch(name) {
                case RestUtils.Headers.URL_TTL:
                    urlTtlSecs = Math.min(maxUrlTtlSecs, RestUtils.getLongHeader(args, RestUtils.Headers.URL_TTL, true));
                    break;
                case RestUtils.Headers.MAX_UPLOAD_SIZE:
                    maxUploadSize = RestUtils.getLongHeader(args, RestUtils.Headers.MAX_UPLOAD_SIZE, true);
                    break;
                default:
                    urlBuilder.append(name).append(PARAMETER_ASSIGN).append(value).append(PARAMETER_SEPARATOR);
                    break;
            }
        }
    }
    if (RestMethod.POST.equals(restMethodInSignedUrl)) {
        urlBuilder.append(RestUtils.Headers.MAX_UPLOAD_SIZE).append(PARAMETER_ASSIGN).append(maxUploadSize).append(PARAMETER_SEPARATOR);
    }
    urlBuilder.append(LINK_EXPIRY_TIME).append(PARAMETER_ASSIGN).append(time.seconds() + urlTtlSecs);
    // since all strings came from the URL, they are assumed to be url encodable.
    return urlBuilder.toString();
}
Also used : RestServiceException(com.github.ambry.rest.RestServiceException) Map(java.util.Map) RestMethod(com.github.ambry.rest.RestMethod)

Example 3 with RestMethod

use of com.github.ambry.rest.RestMethod in project ambry by linkedin.

the class GetSignedUrlHandler method handle.

/**
 * Handles a request for getting signed URLs.
 * @param restRequest the {@link RestRequest} that contains the request parameters.
 * @param restResponseChannel the {@link RestResponseChannel} where headers should be set.
 * @param callback the {@link Callback} to invoke when the response is ready (or if there is an exception).
 * @throws RestServiceException if required parameters are not found or are invalid
 */
void handle(RestRequest restRequest, RestResponseChannel restResponseChannel, Callback<ReadableStreamChannel> callback) throws RestServiceException {
    RestRequestMetrics requestMetrics = restRequest.getSSLSession() != null ? metrics.getSignedUrlSSLMetrics : metrics.getSignedUrlMetrics;
    restRequest.getMetricsTracker().injectMetrics(requestMetrics);
    String restMethodInSignedUrlStr = RestUtils.getHeader(restRequest.getArgs(), RestUtils.Headers.URL_TYPE, true);
    RestMethod restMethodInUrl;
    try {
        restMethodInUrl = RestMethod.valueOf(restMethodInSignedUrlStr);
    } catch (IllegalArgumentException e) {
        throw new RestServiceException("Unrecognized RestMethod: " + restMethodInSignedUrlStr, RestServiceErrorCode.InvalidArgs);
    }
    securityService.processRequest(restRequest, new SecurityProcessRequestCallback(restRequest, restMethodInUrl, restResponseChannel, callback));
}
Also used : RestServiceException(com.github.ambry.rest.RestServiceException) RestRequestMetrics(com.github.ambry.rest.RestRequestMetrics) RestMethod(com.github.ambry.rest.RestMethod)

Example 4 with RestMethod

use of com.github.ambry.rest.RestMethod in project ambry by linkedin.

the class FrontendTestUrlSigningServiceFactory method doRouterExceptionPipelineTest.

// routerExceptionPipelineTest() helpers.
/**
 * Does the exception pipelining test for {@link Router}.
 * @param testRouter the {@link Router} to use to while creating {@link AmbryBlobStorageService}.
 * @param exceptionMsg the expected exception message.
 * @throws Exception
 */
private void doRouterExceptionPipelineTest(FrontendTestRouter testRouter, String exceptionMsg) throws Exception {
    ambryBlobStorageService = new AmbryBlobStorageService(frontendConfig, frontendMetrics, responseHandler, testRouter, clusterMap, idConverterFactory, securityServiceFactory, accountService, urlSigningService, accountAndContainerInjector);
    ambryBlobStorageService.start();
    for (RestMethod restMethod : RestMethod.values()) {
        switch(restMethod) {
            case HEAD:
                testRouter.exceptionOpType = FrontendTestRouter.OpType.GetBlob;
                checkRouterExceptionPipeline(exceptionMsg, createRestRequest(restMethod, referenceBlobIdStr, null, null));
                break;
            case GET:
                testRouter.exceptionOpType = FrontendTestRouter.OpType.GetBlob;
                checkRouterExceptionPipeline(exceptionMsg, createRestRequest(restMethod, referenceBlobIdStr, null, null));
                break;
            case POST:
                testRouter.exceptionOpType = FrontendTestRouter.OpType.PutBlob;
                JSONObject headers = new JSONObject();
                setAmbryHeadersForPut(headers, 7200, !refContainer.isCacheable(), "routerExceptionPipelineTest", "application/octet-stream", "routerExceptionPipelineTest", refAccount.getName(), refContainer.getName());
                checkRouterExceptionPipeline(exceptionMsg, createRestRequest(restMethod, "/", headers, null));
                break;
            case DELETE:
                testRouter.exceptionOpType = FrontendTestRouter.OpType.DeleteBlob;
                checkRouterExceptionPipeline(exceptionMsg, createRestRequest(restMethod, referenceBlobIdStr, null, null));
                break;
            default:
                break;
        }
    }
}
Also used : JSONObject(org.json.JSONObject) RestMethod(com.github.ambry.rest.RestMethod)

Example 5 with RestMethod

use of com.github.ambry.rest.RestMethod in project ambry by linkedin.

the class FrontendTestUrlSigningServiceFactory method doExternalServicesBadInputTest.

/**
 * Does the tests to check for exception pipelining for exceptions returned/thrown by external services.
 * @param restMethods the {@link RestMethod} types for which the test has to be run.
 * @param expectedExceptionMsg the expected exception message.
 * @param expectRouterCall if the router should have returned a value before the exception occurs.
 * @throws JSONException
 */
private void doExternalServicesBadInputTest(RestMethod[] restMethods, String expectedExceptionMsg, boolean expectRouterCall) throws JSONException {
    for (RestMethod restMethod : restMethods) {
        if (restMethod.equals(RestMethod.UNKNOWN) || restMethod.equals(RestMethod.PUT)) {
            continue;
        }
        JSONObject headers = new JSONObject();
        List<ByteBuffer> contents = null;
        if (restMethod.equals(RestMethod.POST)) {
            setAmbryHeadersForPut(headers, 7200, !refContainer.isCacheable(), "doExternalServicesBadInputTest", "application/octet-stream", "doExternalServicesBadInputTest", refAccount.getName(), refContainer.getName());
            contents = new ArrayList<>(1);
            contents.add(null);
        }
        String blobIdStr = new BlobId(blobIdVersion, BlobId.BlobIdType.NATIVE, (byte) -1, Account.UNKNOWN_ACCOUNT_ID, Container.UNKNOWN_CONTAINER_ID, clusterMap.getAllPartitionIds().get(0), false).getID();
        try {
            doOperation(createRestRequest(restMethod, blobIdStr, headers, contents), new MockRestResponseChannel());
            fail("Operation " + restMethod + " should have failed because an external service would have thrown an exception");
        } catch (Exception e) {
            assertEquals("Unexpected exception message", expectedExceptionMsg, e.getMessage());
            if (expectRouterCall && restMethod == RestMethod.GET) {
                assertNotNull("expected router.getBlob() call to provide a response to responseHandler", responseHandler.getResponse());
            }
        }
    }
}
Also used : JSONObject(org.json.JSONObject) MockRestResponseChannel(com.github.ambry.rest.MockRestResponseChannel) ByteBuffer(java.nio.ByteBuffer) BlobId(com.github.ambry.commons.BlobId) URISyntaxException(java.net.URISyntaxException) JSONException(org.json.JSONException) InvocationTargetException(java.lang.reflect.InvocationTargetException) RestServiceException(com.github.ambry.rest.RestServiceException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) RouterException(com.github.ambry.router.RouterException) RestMethod(com.github.ambry.rest.RestMethod)

Aggregations

RestMethod (com.github.ambry.rest.RestMethod)10 RestServiceException (com.github.ambry.rest.RestServiceException)8 MockRestRequest (com.github.ambry.rest.MockRestRequest)4 MockRestResponseChannel (com.github.ambry.rest.MockRestResponseChannel)4 RestRequest (com.github.ambry.rest.RestRequest)4 RestUtils (com.github.ambry.rest.RestUtils)3 Test (org.junit.Test)3 BlobId (com.github.ambry.commons.BlobId)2 BlobInfo (com.github.ambry.messageformat.BlobInfo)2 BlobProperties (com.github.ambry.messageformat.BlobProperties)2 IOException (java.io.IOException)2 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 URISyntaxException (java.net.URISyntaxException)2 ByteBuffer (java.nio.ByteBuffer)2 Date (java.util.Date)2 JSONObject (org.json.JSONObject)2 MetricRegistry (com.codahale.metrics.MetricRegistry)1 Account (com.github.ambry.account.Account)1 Container (com.github.ambry.account.Container)1 InMemAccountService (com.github.ambry.account.InMemAccountService)1