From: <jbo...@li...> - 2006-05-27 19:25:05
|
Author: adamw Date: 2006-05-27 15:24:57 -0400 (Sat, 27 May 2006) New Revision: 4453 Added: labs/shotoku/trunk/shotoku-file-access/ labs/shotoku/trunk/shotoku-file-access/maven.xml labs/shotoku/trunk/shotoku-file-access/project.properties labs/shotoku/trunk/shotoku-file-access/project.xml labs/shotoku/trunk/shotoku-file-access/shotoku-file-access.iml labs/shotoku/trunk/shotoku-file-access/src/ labs/shotoku/trunk/shotoku-file-access/src/java/ labs/shotoku/trunk/shotoku-file-access/src/java/org/ labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/ labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/shotoku/ labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/shotoku/fileaccess/ labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/shotoku/fileaccess/ContentInformation.java labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/shotoku/fileaccess/FileAccessConfiguration.java labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/shotoku/fileaccess/FileAccessConfigurationWatcher.java labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/shotoku/fileaccess/FileAccessMonitor.java labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/shotoku/fileaccess/FileAccessServlet.java labs/shotoku/trunk/shotoku-file-access/src/web/ labs/shotoku/trunk/shotoku-file-access/src/web/WEB-INF/ labs/shotoku/trunk/shotoku-file-access/src/web/WEB-INF/jboss-app.xml labs/shotoku/trunk/shotoku-file-access/src/web/WEB-INF/jboss-web.xml labs/shotoku/trunk/shotoku-file-access/src/web/WEB-INF/web.xml Modified: labs/shotoku/trunk/project.properties Log: http://jira.jboss.com/jira/browse/JBSHOTOKU-84 Modified: labs/shotoku/trunk/project.properties =================================================================== --- labs/shotoku/trunk/project.properties 2006-05-27 01:27:09 UTC (rev 4452) +++ labs/shotoku/trunk/project.properties 2006-05-27 19:24:57 UTC (rev 4453) @@ -5,7 +5,7 @@ shotoku.sar.dir=shotoku.sar shotoku.subprojects.cms=base,files,jcr,svn -shotoku.subprojects=${shotoku.subprojects.cms},aop,test,web,admin,feeds,portal +shotoku.subprojects=${shotoku.subprojects.cms},aop,test,web,admin,feeds,portal,file-access maven.final.name=${pom.artifactId} Property changes on: labs/shotoku/trunk/shotoku-file-access ___________________________________________________________________ Name: svn:ignore + target Added: labs/shotoku/trunk/shotoku-file-access/maven.xml =================================================================== --- labs/shotoku/trunk/shotoku-file-access/maven.xml 2006-05-27 01:27:09 UTC (rev 4452) +++ labs/shotoku/trunk/shotoku-file-access/maven.xml 2006-05-27 19:24:57 UTC (rev 4453) @@ -0,0 +1,29 @@ +<!-- + JBoss, the OpenSource J2EE webOS + Distributable under LGPL license. + See terms of license at gnu.org. + --> +<project xmlns:j="jelly:core" xmlns:ant="jelly:ant" xmlns:u="jelly:util"> + <!-- Default war-project goals --> + + <goal name="build"> + <attainGoal name="jar" /> + <attainGoal name="war" /> + </goal> + + <goal name="deploy"> + <ant:copy + file="target/shotoku-file-access.war" + todir="${local.deploy.dir}" /> + </goal> + + <goal name="clean"> + <attainGoal name="prj-clean" /> + </goal> + + <goal name="all"> + <attainGoal name="clean" /> + <attainGoal name="build" /> + <attainGoal name="deploy" /> + </goal> +</project> Added: labs/shotoku/trunk/shotoku-file-access/project.properties =================================================================== --- labs/shotoku/trunk/shotoku-file-access/project.properties 2006-05-27 01:27:09 UTC (rev 4452) +++ labs/shotoku/trunk/shotoku-file-access/project.properties 2006-05-27 19:24:57 UTC (rev 4453) @@ -0,0 +1,6 @@ +maven.repo.remote=http://repository.atlassian.com,http://www.ibiblio.org/maven +maven.junit.fork=yes +maven.war.src=${basedir}/src/web + +maven.final.name=${pom.artifactId} + Added: labs/shotoku/trunk/shotoku-file-access/project.xml =================================================================== --- labs/shotoku/trunk/shotoku-file-access/project.xml 2006-05-27 01:27:09 UTC (rev 4452) +++ labs/shotoku/trunk/shotoku-file-access/project.xml 2006-05-27 19:24:57 UTC (rev 4453) @@ -0,0 +1,47 @@ +<?xml version='1.0' encoding='ISO-8859-1'?> +<!-- + JBoss, the OpenSource J2EE webOS + Distributable under LGPL license. + See terms of license at gnu.org. + --> +<project> + <pomVersion>3</pomVersion> + <extend>../project.xml</extend> + <id>shotoku-file-access</id> + <name>Shotoku File Access</name> + <currentVersion>1.0</currentVersion> + <organization> + <name>Adam Warski</name> + </organization> + <description></description> + + <dependencies> + <dependency> + <groupId>shotoku</groupId> + <artifactId>shotoku-base</artifactId> + <jar>shotoku-base.jar</jar> + </dependency> + + <dependency> + <groupId>shotoku</groupId> + <artifactId>shotoku-aop</artifactId> + <jar>shotoku-aop.jar</jar> + </dependency> + + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet</artifactId> + <jar>javax.servlet.jar</jar> + </dependency> + </dependencies> + + <build> + <sourceDirectory>src/java</sourceDirectory> + <resources> + <resource> + <directory>src/etc/</directory> + <include>**/*.xml</include> + </resource> + </resources> + </build> +</project> Added: labs/shotoku/trunk/shotoku-file-access/shotoku-file-access.iml =================================================================== --- labs/shotoku/trunk/shotoku-file-access/shotoku-file-access.iml 2006-05-27 01:27:09 UTC (rev 4452) +++ labs/shotoku/trunk/shotoku-file-access/shotoku-file-access.iml 2006-05-27 19:24:57 UTC (rev 4453) @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module version="4" relativePaths="true" type="JAVA_MODULE"> + <component name="ModuleRootManager" /> + <component name="NewModuleRootManager"> + <output url="file://$MODULE_DIR$/target" /> + <exclude-output /> + <content url="file://$MODULE_DIR$"> + <sourceFolder url="file://$MODULE_DIR$/src/java" isTestSource="false" /> + </content> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + <orderEntry type="module" module-name="shotoku-base" /> + <orderEntry type="module" module-name="shotoku-aop" /> + <orderEntry type="library" name="jboss" level="application" /> + <orderEntryProperties /> + </component> +</module> + Added: labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/shotoku/fileaccess/ContentInformation.java =================================================================== --- labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/shotoku/fileaccess/ContentInformation.java 2006-05-27 01:27:09 UTC (rev 4452) +++ labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/shotoku/fileaccess/ContentInformation.java 2006-05-27 19:24:57 UTC (rev 4453) @@ -0,0 +1,30 @@ +package org.jboss.shotoku.fileaccess; + +import java.io.InputStream; + +/** + * @author Adam Warski (ad...@as...) + */ +public class ContentInformation { + private String mimeType; + private long contentLenght; + private InputStream is; + + public ContentInformation(String mimeType, long contentLenght, InputStream is) { + this.mimeType = mimeType; + this.contentLenght = contentLenght; + this.is = is; + } + + public String getMimeType() { + return mimeType; + } + + public long getContentLenght() { + return contentLenght; + } + + public InputStream getIs() { + return is; + } +} Added: labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/shotoku/fileaccess/FileAccessConfiguration.java =================================================================== --- labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/shotoku/fileaccess/FileAccessConfiguration.java 2006-05-27 01:27:09 UTC (rev 4452) +++ labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/shotoku/fileaccess/FileAccessConfiguration.java 2006-05-27 19:24:57 UTC (rev 4453) @@ -0,0 +1,59 @@ +package org.jboss.shotoku.fileaccess; + +import org.apache.log4j.Logger; + +import java.util.List; +import java.util.Properties; +import java.util.ArrayList; +import java.util.regex.Pattern; + +/** + * @author Adam Warski (ad...@as...) + */ +public class FileAccessConfiguration { + private static final Logger log = Logger.getLogger(FileAccessServlet.class); + + private List<FileAccessMonitor> monitors; + private List<Pattern> allowedPatterns; + + public FileAccessConfiguration(Properties props) { + monitors = new ArrayList<FileAccessMonitor>(); + + // Reading monitor classes. + String[] monitorsTokens = props.getProperty("monitor.stack", "").split("[,]"); + for (String monitorToken : monitorsTokens) { + try { + monitors.add((FileAccessMonitor) Class.forName(monitorToken).newInstance()); + } catch (Exception e) { + log.error("Error loading a file access monitor.", e); + } + } + + // Reading allowed patterns. + allowedPatterns = new ArrayList<Pattern>(); + + // 1. Allowed paths which contain a given string. + String[] containingTokens = props.getProperty("allowed.paths.containing", "").split("[,]"); + for (String containingToken : containingTokens) { + allowedPatterns.add(Pattern.compile(".*" + Pattern.quote(containingToken) + ".*")); + } + } + + public List<FileAccessMonitor> getMonitors() { + return monitors; + } + + public boolean checkPath(String path) { + if (path.indexOf("..") != -1) { + return false; + } + + for (Pattern p : allowedPatterns) { + if (p.matcher(path).matches()) { + return true; + } + } + + return false; + } +} Added: labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/shotoku/fileaccess/FileAccessConfigurationWatcher.java =================================================================== --- labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/shotoku/fileaccess/FileAccessConfigurationWatcher.java 2006-05-27 01:27:09 UTC (rev 4452) +++ labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/shotoku/fileaccess/FileAccessConfigurationWatcher.java 2006-05-27 19:24:57 UTC (rev 4453) @@ -0,0 +1,50 @@ +package org.jboss.shotoku.fileaccess; + +import org.jboss.shotoku.ContentManager; +import org.jboss.shotoku.exceptions.ResourceDoesNotExist; +import org.jboss.shotoku.cache.ShotokuPropertiesWatcher; +import org.jboss.shotoku.cache.ShotokuResourceWatcher; +import org.jboss.shotoku.cache.ChangeType; +import org.jboss.shotoku.tools.Pair; + +import java.util.Map; +import java.util.Properties; +import java.io.IOException; + +/** + * @author Adam Warski (ad...@as...) + */ +public class FileAccessConfigurationWatcher extends ShotokuResourceWatcher<Pair<String, String>, + FileAccessConfiguration> { + private static final String CONFIG_FILE_NAME = "file-access.properties"; + + private FileAccessConfiguration getConfiguration(Pair<String, String> key) { + Properties props = new Properties(); + + try { + props.load(getContentManager(key).getNode( + CONFIG_FILE_NAME).getContentInputStream()); + } catch (IOException e) { + e.printStackTrace(); + } catch (ResourceDoesNotExist e) { + // Well ... + e.printStackTrace(); + } + + return new FileAccessConfiguration(props); + } + + public FileAccessConfiguration init(Pair<String, String> key) { + addWatchedPath(key, CONFIG_FILE_NAME); + return getConfiguration(key); + } + + protected ContentManager initContentManager(Pair<String, String> key) { + return ContentManager.getContentManager(key.getFirst(), key.getSecond()); + } + + protected void update(Pair<String, String> key, FileAccessConfiguration currentObject, + Map<String, ChangeType> changes) { + put(key, getConfiguration(key)); + } +} Added: labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/shotoku/fileaccess/FileAccessMonitor.java =================================================================== --- labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/shotoku/fileaccess/FileAccessMonitor.java 2006-05-27 01:27:09 UTC (rev 4452) +++ labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/shotoku/fileaccess/FileAccessMonitor.java 2006-05-27 19:24:57 UTC (rev 4453) @@ -0,0 +1,26 @@ +package org.jboss.shotoku.fileaccess; + +import org.jboss.shotoku.ContentManager; + +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import java.io.InputStream; +import java.io.FileNotFoundException; + +/** + * @author Adam Warski (ad...@as...) + */ +public interface FileAccessMonitor { + /** + * Invoked when the given resource is requested. Can return information about + * content to transmit. + * @param path Path requested. + * @param cm Associated content manager. + * @param request Servlet request. + * @return Null, if content to transmit should be read from Shotoku in the + * normal way. If not null, content from the returned content information will be + * transmitted. + */ + public ContentInformation resourceRequested(String path, ServletRequest request, + ContentManager cm) throws FileNotFoundException; +} Added: labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/shotoku/fileaccess/FileAccessServlet.java =================================================================== --- labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/shotoku/fileaccess/FileAccessServlet.java 2006-05-27 01:27:09 UTC (rev 4452) +++ labs/shotoku/trunk/shotoku-file-access/src/java/org/jboss/shotoku/fileaccess/FileAccessServlet.java 2006-05-27 19:24:57 UTC (rev 4453) @@ -0,0 +1,123 @@ +package org.jboss.shotoku.fileaccess; + +import org.jboss.shotoku.tools.Pair; +import org.jboss.shotoku.tools.Tools; +import org.jboss.shotoku.ContentManager; +import org.jboss.shotoku.Node; +import org.jboss.shotoku.aop.CacheItem; +import org.apache.log4j.Logger; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.util.Properties; + +/** + * A filter that enables to download files which are stored in a working copy of + * a content repository. + * + * @author adamw + * @author Ryszard Kozmik + * @author Tomasz Szymanski + */ +public class FileAccessServlet extends HttpServlet { + private static final Logger log = Logger.getLogger(FileAccessServlet.class); + + /** + * <code>ACCESS_DENIED</code> - message shown to the client when he tries + * to access a resource to which he doesn't have access. + */ + private final static String ACCESS_DENIED = "Sorry, you don't have access to this resource"; + + private ContentManager contentManager; + private Pair<String, String> confKey; + + @CacheItem + private FileAccessConfigurationWatcher conf; + + public void init(ServletConfig conf) { + contentManager = ContentManager.getContentManager( + conf.getInitParameter("contentManagerId"), + conf.getInitParameter("contentManagerPrefix")); + + confKey = new Pair<String, String>( + contentManager.getId(), + conf.getInitParameter("configFileDirectory")); + } + + private void writeErrorMessage(HttpServletResponse response) throws IOException { + response.setContentType("text/html"); + response.getWriter().println(FileAccessServlet.ACCESS_DENIED); + } + + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + FileAccessConfiguration fac = conf.get(confKey); + + String requestURI = request.getRequestURI(); + /* + * The request URI has the form: /.war-name/path/to/resource, so we + * want to get the part /path/to/resource. + */ + String requestedRes = requestURI.split("[/]", 3)[2]; + + // Now we get rid of any query strings. + String path = requestedRes; + int qmPos = requestedRes.indexOf('?'); + if (qmPos != -1) { + path = requestedRes.substring(0, qmPos); + } + + try { + // Checking if we can allow access to this resource. + if (!fac.checkPath(path)) { + writeErrorMessage(response); + } + + ContentInformation ci = null; + + // Notifying each monitor. Also checking, if any information about content + // to transmit is returned. + for (FileAccessMonitor fam : fac.getMonitors()) { + ContentInformation ciTemp = fam.resourceRequested(path, request, contentManager); + if (ciTemp != null) { + ci = ciTemp; + } + } + + if (ci == null) { + Node requestedNode = contentManager.getNode(requestedRes); + ci = new ContentInformation(requestedNode.getMimeType(), + requestedNode.getLength(), + requestedNode.getContentInputStream()); + } + + // Setting response parameters + response.setContentType(ci.getMimeType()); + response.setContentLength((int) ci.getContentLenght()); + + // Getting the output stream of the servlet response. + OutputStream os = response.getOutputStream(); + + // Transferring the bytes + try { + Tools.transfer(ci.getIs(), os); + } catch (Exception e2) { + // Nothing that we can really do. Just send an incomplete + // file. + } finally { + os.close(); + ci.getIs().close(); + } + } catch (Exception e) { + e.printStackTrace(); + writeErrorMessage(response); + } + } + + public void destroy() { + + } +} Added: labs/shotoku/trunk/shotoku-file-access/src/web/WEB-INF/jboss-app.xml =================================================================== --- labs/shotoku/trunk/shotoku-file-access/src/web/WEB-INF/jboss-app.xml 2006-05-27 01:27:09 UTC (rev 4452) +++ labs/shotoku/trunk/shotoku-file-access/src/web/WEB-INF/jboss-app.xml 2006-05-27 19:24:57 UTC (rev 4453) @@ -0,0 +1,3 @@ +<jboss-app> + <app-name>shotokue-file-access</app-name> +</jboss-app> Added: labs/shotoku/trunk/shotoku-file-access/src/web/WEB-INF/jboss-web.xml =================================================================== --- labs/shotoku/trunk/shotoku-file-access/src/web/WEB-INF/jboss-web.xml 2006-05-27 01:27:09 UTC (rev 4452) +++ labs/shotoku/trunk/shotoku-file-access/src/web/WEB-INF/jboss-web.xml 2006-05-27 19:24:57 UTC (rev 4453) @@ -0,0 +1,4 @@ +<?xml version="1.0"?> +<jboss-web> + <context-root>file-access</context-root> +</jboss-web> Added: labs/shotoku/trunk/shotoku-file-access/src/web/WEB-INF/web.xml =================================================================== --- labs/shotoku/trunk/shotoku-file-access/src/web/WEB-INF/web.xml 2006-05-27 01:27:09 UTC (rev 4452) +++ labs/shotoku/trunk/shotoku-file-access/src/web/WEB-INF/web.xml 2006-05-27 19:24:57 UTC (rev 4453) @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<web-app xmlns="http://java.sun.com/xml/ns/j2ee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee + http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" + version="2.4"> + + <servlet> + <servlet-name>fileAccessServlet</servlet-name> + <servlet-class>org.jboss.shotoku.fileaccess.FileAccessServlet</servlet-class> + <init-param> + <param-name>configFileDirectory</param-name> + <param-value>default/file-access</param-value> + </init-param> + <init-param> + <param-name>contentManagerId</param-name> + <param-value>default</param-value> + </init-param> + <init-param> + <param-name>contentManagerPrefix</param-name> + <param-value></param-value> + </init-param> + </servlet> + + <servlet-mapping> + <servlet-name>fileAccessServlet</servlet-name> + <url-pattern>/*</url-pattern> + </servlet-mapping> +</web-app> \ No newline at end of file |