/**
* Licensed to The Apereo Foundation under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
*
* The Apereo Foundation licenses this file to you under the Educational
* Community 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://opensource.org/licenses/ecl2.txt
*
* 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 org.opencastproject.security.urlsigning;
import org.opencastproject.mediapackage.MediaPackageSerializer;
import org.opencastproject.security.api.SecurityService;
import org.opencastproject.security.urlsigning.exception.UrlSigningException;
import org.opencastproject.security.urlsigning.service.UrlSigningService;
import org.opencastproject.security.urlsigning.utils.UrlSigningServiceOsgiUtil;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Dictionary;
/**
* Implementation of a {@link MediaPackageSerializer} that will securely sign urls of a Mediapackage.
*/
public class SigningMediaPackageSerializer implements MediaPackageSerializer, ManagedService {
/** The logging facility */
private static final Logger logger = LoggerFactory.getLogger(SigningMediaPackageSerializer.class);
/** Security service to use for the client's IP address */
private SecurityService securityService;
/** URL Signing Service for Securing Content. */
private UrlSigningService urlSigningService;
private long expireSeconds = UrlSigningServiceOsgiUtil.DEFAULT_URL_SIGNING_EXPIRE_DURATION;
private Boolean signWithClientIP = UrlSigningServiceOsgiUtil.DEFAULT_SIGN_WITH_CLIENT_IP;
/** Signing of the URL should probably be something of the last things to do */
public static final int RANKING = -1000;
/**
* Creates a new and unconfigured package serializer that will not be able to perform any redirecting.
*/
public SigningMediaPackageSerializer() {
}
/** OSGi DI */
void setSecurityService(SecurityService securityService) {
this.securityService = securityService;
}
/** OSGi callback for UrlSigningService */
public void setUrlSigningService(UrlSigningService urlSigningService) {
this.urlSigningService = urlSigningService;
}
/** OSGi callback if properties file is present */
@SuppressWarnings("rawtypes")
@Override
public void updated(Dictionary properties) throws ConfigurationException {
expireSeconds = UrlSigningServiceOsgiUtil.getUpdatedSigningExpiration(properties, this.getClass().getSimpleName());
signWithClientIP = UrlSigningServiceOsgiUtil.getUpdatedSignWithClientIP(properties,
this.getClass().getSimpleName());
}
/**
* {@inheritDoc}
*
* @see org.opencastproject.mediapackage.MediaPackageSerializer#encodeURI(URI)
*/
@Override
public URI encodeURI(URI uri) throws URISyntaxException {
if (uri == null)
throw new IllegalArgumentException("Argument uri is null");
return uri;
}
/**
* {@inheritDoc}
*
* @see org.opencastproject.mediapackage.MediaPackageSerializer#decodeURI(URI)
*/
@Override
public URI decodeURI(URI uri) throws URISyntaxException {
if (uri == null)
throw new IllegalArgumentException("Argument uri is null");
return sign(uri);
}
@Override
public int getRanking() {
return RANKING;
}
@Override
public String toString() {
return "URL Signing MediaPackage Serializer";
}
/**
* This method is signing the URI with a policy to expire it.
*
* @param uri
* the URI to sign
*
* @return the signed URI
* @throws URISyntaxException
* if the input URI contains syntax errors
*/
private URI sign(URI uri) throws URISyntaxException {
String path = uri.toString();
if (urlSigningService != null && urlSigningService.accepts(path)) {
try {
String clientIP = null;
if (signWithClientIP) {
clientIP = securityService.getUserIP();
}
path = urlSigningService.sign(path, expireSeconds, null, clientIP);
} catch (UrlSigningException e) {
logger.debug("Unable to sign url '" + path + "' so not adding a signed query string.");
}
}
return new URI(path);
}
protected Long getExpirationSeconds() {
return expireSeconds;
}
}