Search in sources :

Example 1 with UrlSigningException

use of org.opencastproject.security.urlsigning.exception.UrlSigningException in project opencast by opencast.

the class ToolsEndpoint method getVideoEditor.

@GET
@Path("{mediapackageid}/editor.json")
@Produces(MediaType.APPLICATION_JSON)
@RestQuery(name = "getVideoEditor", description = "Returns all the information required to get the editor tool started", returnDescription = "JSON object", pathParameters = { @RestParameter(name = "mediapackageid", description = "The id of the media package", isRequired = true, type = RestParameter.Type.STRING) }, reponses = { @RestResponse(description = "Media package found", responseCode = SC_OK), @RestResponse(description = "Media package not found", responseCode = SC_NOT_FOUND) })
public Response getVideoEditor(@PathParam("mediapackageid") final String mediaPackageId) throws IndexServiceException, NotFoundException {
    if (!isEditorAvailable(mediaPackageId))
        return R.notFound();
    // Select tracks
    final Event event = getEvent(mediaPackageId).get();
    final MediaPackage mp = index.getEventMediapackage(event);
    List<MediaPackageElement> previewPublications = getPreviewElementsFromPublication(getInternalPublication(mp));
    // Collect previews and tracks
    List<JValue> jPreviews = new ArrayList<>();
    List<JValue> jTracks = new ArrayList<>();
    for (MediaPackageElement element : previewPublications) {
        final URI elementUri;
        if (urlSigningService.accepts(element.getURI().toString())) {
            try {
                String clientIP = null;
                if (signWithClientIP) {
                    clientIP = securityService.getUserIP();
                }
                elementUri = new URI(urlSigningService.sign(element.getURI().toString(), expireSeconds, null, clientIP));
            } catch (URISyntaxException e) {
                logger.error("Error while trying to sign the preview urls because: {}", getStackTrace(e));
                throw new WebApplicationException(e, SC_INTERNAL_SERVER_ERROR);
            } catch (UrlSigningException e) {
                logger.error("Error while trying to sign the preview urls because: {}", getStackTrace(e));
                throw new WebApplicationException(e, SC_INTERNAL_SERVER_ERROR);
            }
        } else {
            elementUri = element.getURI();
        }
        jPreviews.add(obj(f("uri", v(elementUri.toString())), f("flavor", v(element.getFlavor().getType()))));
        if (!Type.Track.equals(element.getElementType()))
            continue;
        JObject jTrack = obj(f("id", v(element.getIdentifier())), f("flavor", v(element.getFlavor().getType())));
        // Check if there's a waveform for the current track
        Opt<Attachment> optWaveform = getWaveformForTrack(mp, element);
        if (optWaveform.isSome()) {
            final URI waveformUri;
            if (urlSigningService.accepts(element.getURI().toString())) {
                try {
                    waveformUri = new URI(urlSigningService.sign(optWaveform.get().getURI().toString(), expireSeconds, null, null));
                } catch (URISyntaxException e) {
                    logger.error("Error while trying to serialize the waveform urls because: {}", getStackTrace(e));
                    throw new WebApplicationException(e, SC_INTERNAL_SERVER_ERROR);
                } catch (UrlSigningException e) {
                    logger.error("Error while trying to sign the preview urls because: {}", getStackTrace(e));
                    throw new WebApplicationException(e, SC_INTERNAL_SERVER_ERROR);
                }
            } else {
                waveformUri = optWaveform.get().getURI();
            }
            jTracks.add(jTrack.merge(obj(f("waveform", v(waveformUri.toString())))));
        } else {
            jTracks.add(jTrack);
        }
    }
    // Get existing segments
    List<JValue> jSegments = new ArrayList<>();
    for (Tuple<Long, Long> segment : getSegments(mp)) {
        jSegments.add(obj(f(START_KEY, v(segment.getA())), f(END_KEY, v(segment.getB()))));
    }
    // Get workflows
    List<JValue> jWorkflows = new ArrayList<>();
    for (WorkflowDefinition workflow : getEditingWorkflows()) {
        jWorkflows.add(obj(f("id", v(workflow.getId())), f("name", v(workflow.getTitle(), Jsons.BLANK))));
    }
    return RestUtils.okJson(obj(f("title", v(mp.getTitle(), Jsons.BLANK)), f("date", v(event.getRecordingStartDate(), Jsons.BLANK)), f("series", obj(f("id", v(event.getSeriesId(), Jsons.BLANK)), f("title", v(event.getSeriesName(), Jsons.BLANK)))), f("presenters", arr($(event.getPresenters()).map(Functions.stringToJValue))), f("previews", arr(jPreviews)), f(TRACKS_KEY, arr(jTracks)), f("duration", v(mp.getDuration())), f(SEGMENTS_KEY, arr(jSegments)), f("workflows", arr(jWorkflows))));
}
Also used : WebApplicationException(javax.ws.rs.WebApplicationException) ArrayList(java.util.ArrayList) WorkflowDefinition(org.opencastproject.workflow.api.WorkflowDefinition) Attachment(org.opencastproject.mediapackage.Attachment) URISyntaxException(java.net.URISyntaxException) UrlSigningException(org.opencastproject.security.urlsigning.exception.UrlSigningException) URI(java.net.URI) MediaPackageElement(org.opencastproject.mediapackage.MediaPackageElement) JValue(com.entwinemedia.fn.data.json.JValue) MediaPackage(org.opencastproject.mediapackage.MediaPackage) Event(org.opencastproject.index.service.impl.index.event.Event) JObject(com.entwinemedia.fn.data.json.JObject) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) RestQuery(org.opencastproject.util.doc.rest.RestQuery)

Example 2 with UrlSigningException

use of org.opencastproject.security.urlsigning.exception.UrlSigningException in project opencast by opencast.

the class GenericUrlSigningProviderTest method testMultitenantSign.

@Test
public void testMultitenantSign() throws UrlSigningException, ConfigurationException {
    properties.put(GenericUrlSigningProvider.ID_PREFIX + ".1", KEY_ID);
    properties.put(GenericUrlSigningProvider.URL_PREFIX + ".1", MATCHING_URI);
    properties.put(GenericUrlSigningProvider.KEY_PREFIX + ".1", KEY);
    properties.put(GenericUrlSigningProvider.ID_PREFIX + ".2", ORGANIZATION_A_KEY_ID);
    properties.put(GenericUrlSigningProvider.URL_PREFIX + ".2", ORGANIZATION_A_MATCHING_URI);
    properties.put(GenericUrlSigningProvider.KEY_PREFIX + ".2", ORGANIZATION_A_KEY);
    properties.put(GenericUrlSigningProvider.ORGANIZATION_PREFIX + ".2", ORGANIZATION_A_ID);
    properties.put(GenericUrlSigningProvider.ID_PREFIX + ".3", ORGANIZATION_B_KEY_ID);
    properties.put(GenericUrlSigningProvider.URL_PREFIX + ".3", ORGANIZATION_B_MATCHING_URI);
    properties.put(GenericUrlSigningProvider.KEY_PREFIX + ".3", ORGANIZATION_B_KEY);
    properties.put(GenericUrlSigningProvider.ORGANIZATION_PREFIX + ".3", ORGANIZATION_B_ID);
    signerA.updated(properties);
    signerB.updated(properties);
    DateTime before = new DateTime(2020, 03, 01, 00, 46, 17, 0, DateTimeZone.UTC);
    Policy policy;
    String result;
    boolean exceptionThrown;
    // Organization A can sign its URLs using its key
    policy = Policy.mkSimplePolicy(ORGANIZATION_A_RESOURCE_PATH, before);
    result = signerA.sign(policy);
    logger.info(result);
    assertEquals("http://organization-a.opencast.org/path/to/resource.mp4?policy=eyJTdGF0ZW1lbnQiOnsiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6MTU4MzAyMzU3NzAwMH0sIlJlc291cmNlIjoiaHR0cDpcL1wvb3JnYW5pemF0aW9uLWEub3BlbmNhc3Qub3JnXC9wYXRoXC90b1wvcmVzb3VyY2UubXA0In19&keyId=key-id-organization-a&signature=ea715d6ff561f49bb6e2cb8cc3e925029e139f14eeda62fc92573f362c694423", result);
    // Organization A can sign URLs not specific to any organization
    policy = Policy.mkSimplePolicy(RESOURCE_PATH, before);
    result = signerA.sign(policy);
    logger.info(result);
    assertEquals("http://www.opencast.org/path/to/resource.mp4?policy=eyJTdGF0ZW1lbnQiOnsiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6MTU4MzAyMzU3NzAwMH0sIlJlc291cmNlIjoiaHR0cDpcL1wvd3d3Lm9wZW5jYXN0Lm9yZ1wvcGF0aFwvdG9cL3Jlc291cmNlLm1wNCJ9fQ&keyId=theId&signature=5b45e678275e6bc7b06a579f7f42e9a7ea5c58f1da130701db532f121e363e98", result);
    // Organization A cannot sign URLs of organization B
    exceptionThrown = false;
    policy = Policy.mkSimplePolicy(ORGANIZATION_B_RESOURCE_PATH, before);
    try {
        result = signerA.sign(policy);
    } catch (UrlSigningException e) {
        exceptionThrown = true;
    }
    assertTrue(exceptionThrown);
    // Organization B can sign its URLs using its key
    policy = Policy.mkSimplePolicy(ORGANIZATION_B_RESOURCE_PATH, before);
    result = signerB.sign(policy);
    logger.info(result);
    assertEquals("http://organization-b.opencast.org/path/to/resource.mp4?policy=eyJTdGF0ZW1lbnQiOnsiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6MTU4MzAyMzU3NzAwMH0sIlJlc291cmNlIjoiaHR0cDpcL1wvb3JnYW5pemF0aW9uLWIub3BlbmNhc3Qub3JnXC9wYXRoXC90b1wvcmVzb3VyY2UubXA0In19&keyId=key-id-organizatino-b&signature=a6d803d4766f808bf2eaabdcf2e9114f85513d3d5596b4a01cb8d2488de816e8", result);
    // Organization B can sign URLs not specific to any organization
    policy = Policy.mkSimplePolicy(RESOURCE_PATH, before);
    result = signerB.sign(policy);
    logger.info(result);
    assertEquals("http://www.opencast.org/path/to/resource.mp4?policy=eyJTdGF0ZW1lbnQiOnsiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6MTU4MzAyMzU3NzAwMH0sIlJlc291cmNlIjoiaHR0cDpcL1wvd3d3Lm9wZW5jYXN0Lm9yZ1wvcGF0aFwvdG9cL3Jlc291cmNlLm1wNCJ9fQ&keyId=theId&signature=5b45e678275e6bc7b06a579f7f42e9a7ea5c58f1da130701db532f121e363e98", result);
    // Organization B cannot sign URLs of organization B
    exceptionThrown = false;
    policy = Policy.mkSimplePolicy(ORGANIZATION_A_RESOURCE_PATH, before);
    try {
        result = signerB.sign(policy);
    } catch (UrlSigningException e) {
        exceptionThrown = true;
    }
    assertTrue(exceptionThrown);
}
Also used : Policy(org.opencastproject.urlsigning.common.Policy) UrlSigningException(org.opencastproject.security.urlsigning.exception.UrlSigningException) DateTime(org.joda.time.DateTime) Test(org.junit.Test)

Example 3 with UrlSigningException

use of org.opencastproject.security.urlsigning.exception.UrlSigningException in project opencast by opencast.

the class TrustedHttpClientImpl method getSignedUrl.

/**
 * If the request is a GET, sign the URL and return a new {@link HttpUriRequest} that is signed.
 *
 * @param httpUriRequest
 *          The possible URI to sign.
 * @return HttpUriRequest if the request is a GET and is configured to be signed.
 * @throws TrustedHttpClientException
 *           Thrown if there is a problem signing the URL.
 */
protected Opt<HttpUriRequest> getSignedUrl(HttpUriRequest httpUriRequest) throws TrustedHttpClientException {
    if (("GET".equalsIgnoreCase(httpUriRequest.getMethod()) || "HEAD".equalsIgnoreCase(httpUriRequest.getMethod())) && ResourceRequestUtil.isNotSigned(httpUriRequest.getURI()) && urlSigningService.accepts(httpUriRequest.getURI().toString())) {
        logger.trace("Signing request with method: {} and URI: {}", httpUriRequest.getMethod(), httpUriRequest.getURI().toString());
        try {
            String signedUrl = urlSigningService.sign(httpUriRequest.getURI().toString(), signedUrlExpiresDuration, null, null);
            HttpRequestBase signedRequest;
            if ("GET".equalsIgnoreCase(httpUriRequest.getMethod())) {
                signedRequest = new HttpGet(signedUrl);
            } else {
                signedRequest = new HttpHead(signedUrl);
            }
            signedRequest.setProtocolVersion(httpUriRequest.getProtocolVersion());
            for (Header header : httpUriRequest.getAllHeaders()) {
                signedRequest.addHeader(header);
            }
            return Opt.some((HttpUriRequest) signedRequest);
        } catch (UrlSigningException e) {
            throw new TrustedHttpClientException(e);
        }
    } else {
        logger.trace("Not signing request with method: {} and URI: {}", httpUriRequest.getMethod(), httpUriRequest.getURI().toString());
        return Opt.none();
    }
}
Also used : HttpRequestBase(org.apache.http.client.methods.HttpRequestBase) Header(org.apache.http.Header) HttpGet(org.apache.http.client.methods.HttpGet) UrlSigningException(org.opencastproject.security.urlsigning.exception.UrlSigningException) TrustedHttpClientException(org.opencastproject.security.api.TrustedHttpClientException) HttpHead(org.apache.http.client.methods.HttpHead)

Example 4 with UrlSigningException

use of org.opencastproject.security.urlsigning.exception.UrlSigningException in project opencast by opencast.

the class AbstractUrlSigningProvider method sign.

@Override
public String sign(Policy policy) throws UrlSigningException {
    if (!accepts(policy.getBaseUrl())) {
        throw UrlSigningException.urlNotSupported();
    }
    // Get the key that matches this URI since there must be one that matches as the base url has been accepted.
    KeyEntry keyEntry = getKeyEntry(policy.getBaseUrl());
    policy.setResourceStrategy(getResourceStrategy());
    try {
        URI uri = new URI(policy.getBaseUrl());
        List<NameValuePair> queryStringParameters = new ArrayList<>();
        if (uri.getQuery() != null) {
            queryStringParameters = URLEncodedUtils.parse(new URI(policy.getBaseUrl()).getQuery(), StandardCharsets.UTF_8);
        }
        queryStringParameters.addAll(URLEncodedUtils.parse(ResourceRequestUtil.policyToResourceRequestQueryString(policy, keyEntry.getId(), keyEntry.getKey()), StandardCharsets.UTF_8));
        return new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), URLEncodedUtils.format(queryStringParameters, StandardCharsets.UTF_8), null).toString();
    } catch (Exception e) {
        getLogger().error("Unable to create signed URL because {}", ExceptionUtils.getStackTrace(e));
        throw new UrlSigningException(e);
    }
}
Also used : NameValuePair(org.apache.http.NameValuePair) ArrayList(java.util.ArrayList) UrlSigningException(org.opencastproject.security.urlsigning.exception.UrlSigningException) URI(java.net.URI) UrlSigningException(org.opencastproject.security.urlsigning.exception.UrlSigningException) URISyntaxException(java.net.URISyntaxException) ConfigurationException(org.osgi.service.cm.ConfigurationException)

Example 5 with UrlSigningException

use of org.opencastproject.security.urlsigning.exception.UrlSigningException in project opencast by opencast.

the class UrlSigningFilter method doFilter.

/**
 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse,
 *      javax.servlet.FilterChain)
 */
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    if (!enabled) {
        chain.doFilter(request, response);
        return;
    }
    if (urlRegularExpressions.size() == 0) {
        logger.debug("There are no regular expressions configured to protect endpoints, skipping filter.");
        chain.doFilter(request, response);
        return;
    }
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;
    if (!("GET".equalsIgnoreCase(httpRequest.getMethod()) || "HEAD".equalsIgnoreCase(httpRequest.getMethod()))) {
        logger.debug("The request '{}' is not a GET or HEAD request so skipping the filter.", httpRequest.getRequestURL());
        chain.doFilter(request, response);
        return;
    }
    boolean matches = false;
    for (String urlRegularExpression : urlRegularExpressions) {
        Pattern p = Pattern.compile(urlRegularExpression);
        Matcher m = p.matcher(httpRequest.getRequestURL());
        if (m.matches()) {
            matches = true;
            break;
        }
    }
    if (!matches) {
        logger.debug("The request '{}' doesn't match any of the configured regular expressions so skipping the filter.", httpRequest.getRequestURL());
        chain.doFilter(request, response);
        return;
    }
    ResourceRequest resourceRequest;
    try {
        resourceRequest = urlSigningVerifier.verify(httpRequest.getQueryString(), httpRequest.getRemoteAddr(), httpRequest.getRequestURL().toString(), strict);
        if (resourceRequest == null) {
            logger.error("Unable to process httpRequest '{}' because we got a null object as the verification.", httpRequest.getRequestURL());
            httpResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Unable to process http request because we got a null object as the verification.");
            return;
        }
        switch(resourceRequest.getStatus()) {
            case Ok:
                logger.trace("The request '{}' matched a regular expression path and was accepted as a properly signed url.", httpRequest.getRequestURL());
                chain.doFilter(httpRequest, response);
                return;
            case BadRequest:
                logger.debug("Unable to process httpRequest '{}' because it was rejected as a Bad Request, usually a problem with query string: {}", httpRequest.getRequestURL(), resourceRequest.getRejectionReason());
                httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST);
                return;
            case Forbidden:
                logger.debug("Unable to process httpRequest '{}' because is was rejected as Forbidden, usually a problem with making policy matching the signature: {}", httpRequest.getRequestURL(), resourceRequest.getRejectionReason());
                httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
                return;
            case Gone:
                logger.debug("Unable to process httpRequest '{}' because is was rejected as Gone: {}", httpRequest.getRequestURL(), resourceRequest.getRejectionReason());
                httpResponse.sendError(HttpServletResponse.SC_GONE);
                return;
            default:
                logger.error("Unable to process httpRequest '{}' because is was rejected as status {} which is not a status we should be handling here. This must be due to a code change and is a bug.: {}", httpRequest.getRequestURL(), resourceRequest.getStatus(), resourceRequest.getRejectionReason());
                httpResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                return;
        }
    } catch (UrlSigningException e) {
        logger.error("Unable to verify request for '{}' with query string '{}' from host '{}' because: {}", httpRequest.getRequestURL(), httpRequest.getQueryString(), httpRequest.getRemoteAddr(), ExceptionUtils.getStackTrace(e));
        httpResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, String.format("%s is unable to verify request for '%s' with query string '%s' from host '%s' because: %s", getName(), httpRequest.getRequestURL(), httpRequest.getQueryString(), httpRequest.getRemoteAddr(), ExceptionUtils.getStackTrace(e)));
        return;
    }
}
Also used : HttpServletRequest(javax.servlet.http.HttpServletRequest) Pattern(java.util.regex.Pattern) Matcher(java.util.regex.Matcher) HttpServletResponse(javax.servlet.http.HttpServletResponse) ResourceRequest(org.opencastproject.urlsigning.common.ResourceRequest) UrlSigningException(org.opencastproject.security.urlsigning.exception.UrlSigningException)

Aggregations

UrlSigningException (org.opencastproject.security.urlsigning.exception.UrlSigningException)5 URI (java.net.URI)2 URISyntaxException (java.net.URISyntaxException)2 ArrayList (java.util.ArrayList)2 JObject (com.entwinemedia.fn.data.json.JObject)1 JValue (com.entwinemedia.fn.data.json.JValue)1 Matcher (java.util.regex.Matcher)1 Pattern (java.util.regex.Pattern)1 HttpServletRequest (javax.servlet.http.HttpServletRequest)1 HttpServletResponse (javax.servlet.http.HttpServletResponse)1 GET (javax.ws.rs.GET)1 Path (javax.ws.rs.Path)1 Produces (javax.ws.rs.Produces)1 WebApplicationException (javax.ws.rs.WebApplicationException)1 Header (org.apache.http.Header)1 NameValuePair (org.apache.http.NameValuePair)1 HttpGet (org.apache.http.client.methods.HttpGet)1 HttpHead (org.apache.http.client.methods.HttpHead)1 HttpRequestBase (org.apache.http.client.methods.HttpRequestBase)1 DateTime (org.joda.time.DateTime)1