diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/keywordsearch_get_desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/keywordsearch_get_desc.xml
index 58ca751178..ce4145e5c2 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/repository/keywordsearch_get_desc.xml
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/keywordsearch_get_desc.xml
@@ -4,5 +4,6 @@
+ guest
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/keywordsearch_get_portlet.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/keywordsearch_get_portlet.ftl
new file mode 100644
index 0000000000..259e749fc5
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/keywordsearch_get_portlet.ftl
@@ -0,0 +1,33 @@
+
+
+
Results ${search.startIndex} - ${search.startIndex + search.totalPageItems - 1} of ${search.totalResults} for ${search.searchTerms} visible to user <#if person??>${person.properties.userName}<#else>unknown#if>.
\ No newline at end of file
diff --git a/config/alfresco/web-scripts-application-context-test.xml b/config/alfresco/web-scripts-application-context-test.xml
index 57751164d7..7cf91a882e 100644
--- a/config/alfresco/web-scripts-application-context-test.xml
+++ b/config/alfresco/web-scripts-application-context-test.xml
@@ -8,11 +8,7 @@
-
-
-
-
-
+
diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml
index 9b0cf6811e..d4f1cdab88 100644
--- a/config/alfresco/web-scripts-application-context.xml
+++ b/config/alfresco/web-scripts-application-context.xml
@@ -63,36 +63,24 @@
-
-
- webscript_default
-
-
-
-
-
-
+
+
+
+
+
+
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
@@ -119,6 +107,7 @@
application/jsonapplication/opensearchdescription+xmltext/plain
+ text/html
diff --git a/source/java/org/alfresco/web/scripts/AbstractWebScript.java b/source/java/org/alfresco/web/scripts/AbstractWebScript.java
index 0ef031dc9c..a2e1c507e6 100644
--- a/source/java/org/alfresco/web/scripts/AbstractWebScript.java
+++ b/source/java/org/alfresco/web/scripts/AbstractWebScript.java
@@ -26,7 +26,6 @@ package org.alfresco.web.scripts;
import java.io.Writer;
import java.util.Date;
-import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
@@ -36,7 +35,6 @@ import org.alfresco.repo.template.AbsoluteUrlMethod;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.ScriptLocation;
-import org.alfresco.service.cmr.repository.TemplateImageResolver;
import org.alfresco.service.cmr.repository.TemplateService;
import org.alfresco.service.descriptor.DescriptorService;
import org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication;
@@ -174,10 +172,9 @@ public abstract class AbstractWebScript implements WebScript
final protected Map createArgModel(WebScriptRequest req)
{
Map args = new ScriptableHashMap();
- Enumeration names = req.getParameterNames();
- while (names.hasMoreElements())
+ String[] names = req.getParameterNames();
+ for (String name : names)
{
- String name = (String)names.nextElement();
args.put(name, req.getParameter(name));
}
return args;
@@ -269,6 +266,7 @@ public abstract class AbstractWebScript implements WebScript
// add template support
model.put("absurl", new AbsoluteUrlMethod(req.getServerPath()));
+ model.put("scripturl", new ScriptUrlMethod(req, res));
model.put("date", new Date());
model.put(TemplateService.KEY_IMAGE_RESOLVER, getWebScriptRegistry().getTemplateImageResolver());
diff --git a/source/java/org/alfresco/web/scripts/BasicAuthenticator.java b/source/java/org/alfresco/web/scripts/BasicAuthenticator.java
deleted file mode 100644
index a4e5160524..0000000000
--- a/source/java/org/alfresco/web/scripts/BasicAuthenticator.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2005-2007 Alfresco Software Limited.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
- * As a special exception to the terms and conditions of version 2.0 of
- * the GPL, you may redistribute this Program in connection with Free/Libre
- * and Open Source Software ("FLOSS") applications as described in Alfresco's
- * FLOSS exception. You should have recieved a copy of the text describing
- * the FLOSS exception, and it is also available here:
- * http://www.alfresco.com/legal/licensing"
- */
-package org.alfresco.web.scripts;
-
-import org.alfresco.repo.security.authentication.AuthenticationException;
-import org.alfresco.repo.security.authentication.AuthenticationUtil;
-import org.alfresco.service.cmr.security.AuthenticationService;
-import org.alfresco.util.Base64;
-import org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication;
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-
-/**
- * HTTP Basic Authentication Interceptor
- *
- * @author davidc
- */
-public class BasicAuthenticator implements MethodInterceptor
-{
- // Logger
- private static final Log logger = LogFactory.getLog(BasicAuthenticator.class);
-
- // dependencies
- private AuthenticationService authenticationService;
-
- /**
- * @param authenticationService
- */
- public void setAuthenticationService(AuthenticationService authenticationService)
- {
- this.authenticationService = authenticationService;
- }
-
- /* (non-Javadoc)
- * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
- */
- public Object invoke(MethodInvocation invocation)
- throws Throwable
- {
- boolean authorized = false;
- String currentUser = null;
- Object retVal = null;
- Object[] args = invocation.getArguments();
- WebScriptRequest request = (WebScriptRequest)args[0];
- WebScript service = (WebScript)invocation.getThis();
- WebScriptDescription description = service.getDescription();
-
- try
- {
- //
- // Determine if user already authenticated
- //
-
- currentUser = AuthenticationUtil.getCurrentUserName();
- if (logger.isDebugEnabled())
- logger.debug("Current authentication: " + (currentUser == null ? "unauthenticated" : "authenticated as " + currentUser));
-
- //
- // validate credentials
- //
-
- boolean isGuest = request.isGuest();
- String authorization = request.getHeader("Authorization");
-
- if (logger.isDebugEnabled())
- {
- logger.debug("Web Service authentication required: " + description.getRequiredAuthentication());
- logger.debug("Guest login: " + isGuest);
- logger.debug("Authorization provided (overrides Guest login): " + (authorization != null && authorization.length() > 0));
- }
-
- // authenticate as guest, if service allows
- if (((authorization == null || authorization.length() == 0) || isGuest)
- && description.getRequiredAuthentication().equals(RequiredAuthentication.guest))
- {
- if (logger.isDebugEnabled())
- logger.debug("Authenticating as Guest");
-
- authenticationService.authenticateAsGuest();
- authorized = true;
- }
-
- // authenticate as specified by HTTP Basic Authentication
- else if (authorization != null && authorization.length() > 0)
- {
- try
- {
- String[] authorizationParts = authorization.split(" ");
- if (!authorizationParts[0].equalsIgnoreCase("basic"))
- {
- throw new WebScriptException("Authorization '" + authorizationParts[0] + "' not supported.");
- }
- String decodedAuthorisation = new String(Base64.decode(authorizationParts[1]));
- String[] parts = decodedAuthorisation.split(":");
-
- if (parts.length == 1)
- {
- if (logger.isDebugEnabled())
- logger.debug("Authenticating ticket " + parts[0]);
-
- // assume a ticket has been passed
- authenticationService.validate(parts[0]);
- authorized = true;
- }
- else
- {
- if (logger.isDebugEnabled())
- logger.debug("Authenticating user " + parts[0]);
-
- // assume username and password passed
- if (parts[0].equals(AuthenticationUtil.getGuestUserName()))
- {
- if (description.getRequiredAuthentication().equals(RequiredAuthentication.guest))
- {
- authenticationService.authenticateAsGuest();
- authorized = true;
- }
- }
- else
- {
- authenticationService.authenticate(parts[0], parts[1].toCharArray());
- authorized = true;
- }
- }
- }
- catch(AuthenticationException e)
- {
- // failed authentication
- }
- }
-
- //
- // execute web script or request authorization
- //
-
- if (authorized)
- {
- retVal = invocation.proceed();
- }
- else
- {
- if (logger.isDebugEnabled())
- logger.debug("Requesting authorization credentials");
-
- WebScriptResponse response = (WebScriptResponse)args[1];
- response.setStatus(401);
- response.setHeader("WWW-Authenticate", "Basic realm=\"Alfresco\"");
- }
- }
- finally
- {
- // reset authentication
- if (authorized)
- {
- authenticationService.clearCurrentSecurityContext();
- if (currentUser != null)
- {
- AuthenticationUtil.setCurrentUser(currentUser);
- }
-
- if (logger.isDebugEnabled())
- logger.debug("Authentication reset: " + (currentUser == null ? "unauthenticated" : "authenticated as " + currentUser));
- }
- }
-
- return retVal;
- }
-
-}
diff --git a/source/java/org/alfresco/web/scripts/BasicHttpAuthenticator.java b/source/java/org/alfresco/web/scripts/BasicHttpAuthenticator.java
new file mode 100644
index 0000000000..9c3fd2252b
--- /dev/null
+++ b/source/java/org/alfresco/web/scripts/BasicHttpAuthenticator.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2005-2007 Alfresco Software Limited.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ * As a special exception to the terms and conditions of version 2.0 of
+ * the GPL, you may redistribute this Program in connection with Free/Libre
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's
+ * FLOSS exception. You should have recieved a copy of the text describing
+ * the FLOSS exception, and it is also available here:
+ * http://www.alfresco.com/legal/licensing"
+ */
+package org.alfresco.web.scripts;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.alfresco.repo.security.authentication.AuthenticationException;
+import org.alfresco.repo.security.authentication.AuthenticationUtil;
+import org.alfresco.service.cmr.security.AuthenticationService;
+import org.alfresco.util.Base64;
+import org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+/**
+ * HTTP Basic Authentication Interceptor
+ *
+ * @author davidc
+ */
+public class BasicHttpAuthenticator implements WebScriptServletAuthenticator
+{
+ // Logger
+ private static final Log logger = LogFactory.getLog(BasicHttpAuthenticator.class);
+
+ // dependencies
+ private AuthenticationService authenticationService;
+
+ /**
+ * @param authenticationService
+ */
+ public void setAuthenticationService(AuthenticationService authenticationService)
+ {
+ this.authenticationService = authenticationService;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
+ */
+ public void authenticate(RequiredAuthentication required, boolean isGuest, HttpServletRequest req, HttpServletResponse res)
+ {
+ boolean authorized = false;
+
+ //
+ // validate credentials
+ //
+
+ String authorization = req.getHeader("Authorization");
+
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("HTTP Authorization provided: " + (authorization != null && authorization.length() > 0));
+ }
+
+ // authenticate as guest, if service allows
+ if (isGuest)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Authenticating as Guest");
+
+ authenticationService.authenticateAsGuest();
+ authorized = true;
+ }
+
+ // authenticate as specified by HTTP Basic Authentication
+ else if (authorization != null && authorization.length() > 0)
+ {
+ try
+ {
+ String[] authorizationParts = authorization.split(" ");
+ if (!authorizationParts[0].equalsIgnoreCase("basic"))
+ {
+ throw new WebScriptException("Authorization '" + authorizationParts[0] + "' not supported.");
+ }
+ String decodedAuthorisation = new String(Base64.decode(authorizationParts[1]));
+ String[] parts = decodedAuthorisation.split(":");
+
+ if (parts.length == 1)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Authenticating ticket " + parts[0]);
+
+ // assume a ticket has been passed
+ authenticationService.validate(parts[0]);
+ authorized = true;
+ }
+ else
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Authenticating user " + parts[0]);
+
+ // assume username and password passed
+ if (parts[0].equals(AuthenticationUtil.getGuestUserName()))
+ {
+ if (required == RequiredAuthentication.guest)
+ {
+ authenticationService.authenticateAsGuest();
+ authorized = true;
+ }
+ }
+ else
+ {
+ authenticationService.authenticate(parts[0], parts[1].toCharArray());
+ authorized = true;
+ }
+ }
+ }
+ catch(AuthenticationException e)
+ {
+ // failed authentication
+ }
+ }
+
+ //
+ // request credentials if not authorized
+ //
+
+ if (!authorized)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Requesting authorization credentials");
+
+ res.setStatus(401);
+ res.setHeader("WWW-Authenticate", "Basic realm=\"Alfresco\"");
+ }
+ }
+
+}
diff --git a/source/java/org/alfresco/web/scripts/DeclarativeWebScriptRegistry.java b/source/java/org/alfresco/web/scripts/DeclarativeWebScriptRegistry.java
index 8af3c70abe..5e12de1401 100644
--- a/source/java/org/alfresco/web/scripts/DeclarativeWebScriptRegistry.java
+++ b/source/java/org/alfresco/web/scripts/DeclarativeWebScriptRegistry.java
@@ -37,23 +37,20 @@ import java.util.TreeMap;
import javax.servlet.ServletContext;
import org.alfresco.service.cmr.repository.TemplateImageResolver;
+import org.alfresco.util.AbstractLifecycleBean;
import org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication;
import org.alfresco.web.scripts.WebScriptDescription.RequiredTransaction;
import org.alfresco.web.scripts.WebScriptDescription.URI;
import org.alfresco.web.ui.common.Utils;
-import org.aopalliance.intercept.MethodInterceptor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
-import org.springframework.aop.framework.ProxyFactory;
-import org.springframework.aop.support.RegexpMethodPointcutAdvisor;
-import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ApplicationEvent;
import org.springframework.web.context.ServletContextAware;
@@ -62,17 +59,14 @@ import org.springframework.web.context.ServletContextAware;
*
* @author davidc
*/
-public class DeclarativeWebScriptRegistry implements WebScriptRegistry, ApplicationContextAware, ServletContextAware, InitializingBean
+public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
+ implements WebScriptRegistry, ServletContextAware, InitializingBean
{
// Logger
private static final Log logger = LogFactory.getLog(DeclarativeWebScriptRegistry.class);
- private ApplicationContext applicationContext;
private ServletContext servletContext;
private String defaultWebScript;
- private MethodInterceptor authenticator;
- private MethodInterceptor serviceLogger;
- private MethodInterceptor serviceTransaction;
private FormatRegistry formatRegistry;
private WebScriptStorage storage;
private TemplateImageResolver imageResolver;
@@ -101,36 +95,6 @@ public class DeclarativeWebScriptRegistry implements WebScriptRegistry, Applicat
this.storage = storage;
}
- /**
- * Sets the web script authenticator
- *
- * @param authenticator
- */
- public void setAuthenticator(MethodInterceptor authenticator)
- {
- this.authenticator = authenticator;
- }
-
- /**
- * Sets the web script logger
- *
- * @param serviceLogger
- */
- public void setServiceLogger(MethodInterceptor serviceLogger)
- {
- this.serviceLogger = serviceLogger;
- }
-
- /**
- * Sets the service transaction
- *
- * @param serviceTransaction
- */
- public void setServiceTransaction(MethodInterceptor serviceTransaction)
- {
- this.serviceTransaction = serviceTransaction;
- }
-
/**
* Sets the default service implementation bean
*
@@ -159,14 +123,6 @@ public class DeclarativeWebScriptRegistry implements WebScriptRegistry, Applicat
this.servletContext = context;
}
- /* (non-Javadoc)
- * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
- */
- public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
- {
- this.applicationContext = applicationContext;
- }
-
/* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
@@ -181,6 +137,33 @@ public class DeclarativeWebScriptRegistry implements WebScriptRegistry, Applicat
};
}
+ /* (non-Javadoc)
+ * @see org.alfresco.web.scripts.WebScriptRegistry#reset()
+ */
+ public void reset()
+ {
+ getTemplateProcessor().resetCache();
+ getScriptProcessor().resetCache();
+ initWebScripts();
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.util.AbstractLifecycleBean#onBootstrap(org.springframework.context.ApplicationEvent)
+ */
+ @Override
+ protected void onBootstrap(ApplicationEvent event)
+ {
+ initWebScripts();
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.util.AbstractLifecycleBean#onShutdown(org.springframework.context.ApplicationEvent)
+ */
+ @Override
+ protected void onShutdown(ApplicationEvent event)
+ {
+ }
+
/**
* Initialise Web Scripts
*
@@ -245,56 +228,17 @@ public class DeclarativeWebScriptRegistry implements WebScriptRegistry, Applicat
}
// construct service implementation
+ ApplicationContext applicationContext = getApplicationContext();
String serviceImplName = (applicationContext.containsBean("webscript." + id)) ? "webscript." + id : defaultWebScript;
AbstractWebScript serviceImpl = (AbstractWebScript)applicationContext.getBean(serviceImplName);
serviceImpl.setDescription(serviceDesc);
serviceImpl.init(this);
- // wrap service implementation in appropriate interceptors (e.g. authentication)
- WebScript serviceImplIF = (WebScript)serviceImpl;
- if (serviceLogger != null && serviceTransaction != null && authenticator != null)
- {
- ProxyFactory authFactory = new ProxyFactory();
- authFactory.addInterface(WebScript.class);
- authFactory.setTarget(serviceImplIF);
-
- // logging interceptor
- if (serviceLogger != null)
- {
- RegexpMethodPointcutAdvisor advisor = new RegexpMethodPointcutAdvisor(".*execute", serviceLogger);
- authFactory.addAdvisor(advisor);
- }
-
- // transaction interceptor
- if (serviceDesc.getRequiredTransaction() != RequiredTransaction.none)
- {
- if (serviceTransaction == null)
- {
- throw new WebScriptException("Web Script Transaction not specified");
- }
- RegexpMethodPointcutAdvisor advisor = new RegexpMethodPointcutAdvisor(".*execute", serviceTransaction);
- authFactory.addAdvisor(advisor);
- }
-
- // authentication interceptor
- if (serviceDesc.getRequiredAuthentication() != RequiredAuthentication.none)
- {
- if (authenticator == null)
- {
- throw new WebScriptException("Web Script Authenticator not specified");
- }
- RegexpMethodPointcutAdvisor advisor = new RegexpMethodPointcutAdvisor(".*execute", authenticator);
- authFactory.addAdvisor(advisor);
- }
-
- serviceImplIF = (WebScript)authFactory.getProxy();
- }
-
if (logger.isDebugEnabled())
logger.debug("Found Web Script " + serviceDescPath + " (id: " + id + ", impl: " + serviceImplName + ", auth: " + serviceDesc.getRequiredAuthentication() + ", trx: " + serviceDesc.getRequiredTransaction() + ")");
// register service and its urls
- webscriptsById.put(id, serviceImplIF);
+ webscriptsById.put(id, serviceImpl);
for (URI uri : serviceDesc.getURIs())
{
// establish static part of url template
@@ -323,7 +267,7 @@ public class DeclarativeWebScriptRegistry implements WebScriptRegistry, Applicat
}
else
{
- webscriptsByURL.put(uriIdx, serviceImplIF);
+ webscriptsByURL.put(uriIdx, serviceImpl);
if (logger.isDebugEnabled())
logger.debug("Registered Web Script URL '" + uriIdx + "'");
@@ -476,7 +420,6 @@ public class DeclarativeWebScriptRegistry implements WebScriptRegistry, Applicat
}
}
-
/* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptRegistry#getWebScripts()
*/
@@ -553,18 +496,7 @@ public class DeclarativeWebScriptRegistry implements WebScriptRegistry, Applicat
{
return this.storage.getScriptProcessor();
}
-
- /* (non-Javadoc)
- * @see org.alfresco.web.scripts.WebScriptRegistry#reset()
- */
- public void reset()
- {
- getTemplateProcessor().resetCache();
- getScriptProcessor().resetCache();
- initWebScripts();
- }
-
/**
* Web Script Match
*
diff --git a/source/java/org/alfresco/web/scripts/ScriptUrlMethod.java b/source/java/org/alfresco/web/scripts/ScriptUrlMethod.java
new file mode 100644
index 0000000000..82eed62143
--- /dev/null
+++ b/source/java/org/alfresco/web/scripts/ScriptUrlMethod.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2005-2007 Alfresco Software Limited.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ * As a special exception to the terms and conditions of version 2.0 of
+ * the GPL, you may redistribute this Program in connection with Free/Libre
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's
+ * FLOSS exception. You should have recieved a copy of the text describing
+ * the FLOSS exception, and it is also available here:
+ * http://www.alfresco.com/legal/licensing"
+ */
+package org.alfresco.web.scripts;
+
+import java.util.List;
+
+import freemarker.template.TemplateMethodModelEx;
+import freemarker.template.TemplateModelException;
+import freemarker.template.TemplateScalarModel;
+
+/**
+ * @author David Caruana
+ *
+ * Custom FreeMarker Template language method.
+ *
+ * Render script url independent of script hosting environment e.g. render inside / outside
+ * portal.
+ *
+ * Usage: scripturl(String url)
+ */
+public final class ScriptUrlMethod implements TemplateMethodModelEx
+{
+ WebScriptRequest req;
+ WebScriptResponse res;
+
+ /**
+ * Construct
+ *
+ * @param basePath base path used to construct absolute url
+ */
+ public ScriptUrlMethod(WebScriptRequest req, WebScriptResponse res)
+ {
+ this.req = req;
+ this.res = res;
+ }
+
+
+ /**
+ * @see freemarker.template.TemplateMethodModel#exec(java.util.List)
+ */
+ public Object exec(List args) throws TemplateModelException
+ {
+ String result = "";
+
+ if (args.size() == 1)
+ {
+ Object arg0 = args.get(0);
+ if (arg0 instanceof TemplateScalarModel)
+ {
+ String arg = ((TemplateScalarModel)arg0).getAsString();
+ String url = req.getServicePath();
+ url += arg;
+ url += (arg.length() > 0) ? "&" : "";
+ url += "guest=" + (req.isGuest() ? "true" : "");
+ url += (req.getFormat().length() > 0) ? "&format=" + req.getFormat() : "";
+ result = res.encodeScriptUrl(url);
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/source/java/org/alfresco/web/scripts/SystemAuthenticator.java b/source/java/org/alfresco/web/scripts/SystemAuthenticator.java
deleted file mode 100644
index f59815e43c..0000000000
--- a/source/java/org/alfresco/web/scripts/SystemAuthenticator.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2005-2007 Alfresco Software Limited.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
- * As a special exception to the terms and conditions of version 2.0 of
- * the GPL, you may redistribute this Program in connection with Free/Libre
- * and Open Source Software ("FLOSS") applications as described in Alfresco's
- * FLOSS exception. You should have recieved a copy of the text describing
- * the FLOSS exception, and it is also available here:
- * http://www.alfresco.com/legal/licensing"
- */
-package org.alfresco.web.scripts;
-
-import org.alfresco.repo.security.authentication.AuthenticationUtil;
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-
-/**
- * System Authentication Interceptor
- *
- * @author davidc
- */
-public class SystemAuthenticator implements MethodInterceptor
-{
- // Logger
- private static final Log logger = LogFactory.getLog(SystemAuthenticator.class);
-
-
- /* (non-Javadoc)
- * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
- */
- public Object invoke(MethodInvocation invocation)
- throws Throwable
- {
- String currentUser = null;
- Object retVal = null;
-
- try
- {
- //
- // Determine if user already authenticated
- //
-
- currentUser = AuthenticationUtil.getCurrentUserName();
- if (logger.isDebugEnabled())
- logger.debug("Current authentication: " + (currentUser == null ? "unauthenticated" : "authenticated as " + currentUser));
-
- //
- // Force system user
- //
-
- if (logger.isDebugEnabled())
- logger.debug("Authenticating as System");
-
- AuthenticationUtil.setSystemUserAsCurrentUser();
-
- //
- // Invoke service
- //
-
- retVal = invocation.proceed();
- }
- finally
- {
- AuthenticationUtil.clearCurrentSecurityContext();
- if (currentUser != null)
- {
- AuthenticationUtil.setCurrentUser(currentUser);
- }
-
- if (logger.isDebugEnabled())
- logger.debug("Authentication reset: " + (currentUser == null ? "unauthenticated" : "authenticated as " + currentUser));
- }
-
- return retVal;
- }
-
-}
diff --git a/source/java/org/alfresco/web/scripts/TestWebScriptServer.java b/source/java/org/alfresco/web/scripts/TestWebScriptServer.java
index 08e226b0b5..fbe320babc 100644
--- a/source/java/org/alfresco/web/scripts/TestWebScriptServer.java
+++ b/source/java/org/alfresco/web/scripts/TestWebScriptServer.java
@@ -88,6 +88,7 @@ public class TestWebScriptServer
this.registry = registry;
}
+
/**
* Sets the Messages resource bundle
*
@@ -162,15 +163,9 @@ public class TestWebScriptServer
MockHttpServletRequest req = createRequest("get", uri);
MockHttpServletResponse res = new MockHttpServletResponse();
- WebScriptMatch match = registry.findWebScript(req.getMethod(), uri);
- if (match == null)
- {
- throw new WebScriptException("No service bound to uri '" + uri + "'");
- }
-
- WebScriptRequest apiReq = new WebScriptRequest(req, match);
- WebScriptResponse apiRes = new WebScriptResponse(res);
- match.getWebScript().execute(apiReq, apiRes);
+ WebScriptRuntime runtime = new WebScriptServletRuntime(registry, transactionService, null, req, res);
+ runtime.executeScript();
+
return res;
}
@@ -346,5 +341,5 @@ public class TestWebScriptServer
return req;
}
-
+
}
diff --git a/source/java/org/alfresco/web/scripts/TrustedAuthenticator.java b/source/java/org/alfresco/web/scripts/TrustedAuthenticator.java
deleted file mode 100644
index e6890a9d4d..0000000000
--- a/source/java/org/alfresco/web/scripts/TrustedAuthenticator.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2005-2007 Alfresco Software Limited.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
- * As a special exception to the terms and conditions of version 2.0 of
- * the GPL, you may redistribute this Program in connection with Free/Libre
- * and Open Source Software ("FLOSS") applications as described in Alfresco's
- * FLOSS exception. You should have recieved a copy of the text describing
- * the FLOSS exception, and it is also available here:
- * http://www.alfresco.com/legal/licensing"
- */
-package org.alfresco.web.scripts;
-
-import org.alfresco.repo.security.authentication.AuthenticationUtil;
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-
-/**
- * Trusted Authentication Interceptor
- *
- * Just use the currently authenticated user
- *
- * @author davidc
- */
-public class TrustedAuthenticator implements MethodInterceptor
-{
- // Logger
- private static final Log logger = LogFactory.getLog(TrustedAuthenticator.class);
-
-
- /* (non-Javadoc)
- * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
- */
- public Object invoke(MethodInvocation invocation)
- throws Throwable
- {
- String currentUser = null;
- Object retVal = null;
-
- try
- {
- //
- // Determine if user already authenticated
- //
-
- currentUser = AuthenticationUtil.getCurrentUserName();
- if (logger.isDebugEnabled())
- logger.debug("Current authentication: " + (currentUser == null ? "unauthenticated" : "authenticated as " + currentUser));
-
- //
- // Use current authentication
- //
-
- //
- // Invoke service
- //
-
- retVal = invocation.proceed();
- }
- finally
- {
- AuthenticationUtil.clearCurrentSecurityContext();
- if (currentUser != null)
- {
- AuthenticationUtil.setCurrentUser(currentUser);
- }
-
- if (logger.isDebugEnabled())
- logger.debug("Authentication reset: " + (currentUser == null ? "unauthenticated" : "authenticated as " + currentUser));
- }
-
- return retVal;
- }
-
-}
diff --git a/source/java/org/alfresco/web/scripts/WebClientAuthenticator.java b/source/java/org/alfresco/web/scripts/WebClientAuthenticator.java
index b4db1db94b..3f7e6f1133 100644
--- a/source/java/org/alfresco/web/scripts/WebClientAuthenticator.java
+++ b/source/java/org/alfresco/web/scripts/WebClientAuthenticator.java
@@ -24,16 +24,16 @@
*/
package org.alfresco.web.scripts;
-import javax.servlet.ServletContext;
+import java.io.IOException;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
-import org.alfresco.repo.security.authentication.AuthenticationUtil;
-import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.web.app.servlet.AuthenticationHelper;
import org.alfresco.web.app.servlet.AuthenticationStatus;
import org.alfresco.web.app.servlet.BaseServlet;
import org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication;
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.context.ServletContextAware;
@@ -44,14 +44,13 @@ import org.springframework.web.context.ServletContextAware;
*
* @author davidc
*/
-public class WebClientAuthenticator implements MethodInterceptor, ServletContextAware
+public class WebClientAuthenticator implements WebScriptServletAuthenticator, ServletContextAware
{
// Logger
private static final Log logger = LogFactory.getLog(WebClientAuthenticator.class);
// dependencies
private ServletContext context;
- private AuthenticationService authenticationService;
/* (non-Javadoc)
@@ -62,112 +61,69 @@ public class WebClientAuthenticator implements MethodInterceptor, ServletContext
this.context = context;
}
- /**
- * @param authenticationService
- */
- public void setAuthenticationService(AuthenticationService authenticationService)
- {
- this.authenticationService = authenticationService;
- }
-
/* (non-Javadoc)
- * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
+ * @see org.alfresco.web.scripts.WebScriptServletAuthenticator#authenticate(org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication, boolean, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
- public Object invoke(MethodInvocation invocation)
- throws Throwable
+ public void authenticate(RequiredAuthentication required, boolean isGuest, HttpServletRequest req, HttpServletResponse res)
{
- String currentUser = null;
- Object retVal = null;
- Object[] args = invocation.getArguments();
- WebScriptRequest request = (WebScriptRequest)args[0];
- WebScriptResponse response = (WebScriptResponse)args[1];
- WebScript service = (WebScript)invocation.getThis();
- WebScriptDescription description = service.getDescription();
AuthenticationStatus status = null;
try
{
- //
- // Determine if user already authenticated
- //
-
- currentUser = AuthenticationUtil.getCurrentUserName();
- if (logger.isDebugEnabled())
- logger.debug("Current authentication: " + (currentUser == null ? "unauthenticated" : "authenticated as " + currentUser));
-
//
// validate credentials
//
- String ticket = request.getParameter("ticket");
- boolean isGuest = request.isGuest();
+ String ticket = req.getParameter("ticket");
if (logger.isDebugEnabled())
{
- logger.debug("Web Script authentication required: " + description.getRequiredAuthentication());
- logger.debug("Guest login: " + isGuest);
- logger.debug("Ticket provided: " + (ticket != null && ticket.length() > 0));
+ logger.debug("Alfresco ticket provided: " + (ticket != null && ticket.length() > 0));
}
if (ticket != null && ticket.length() > 0)
{
if (logger.isDebugEnabled())
logger.debug("Authenticating ticket " + ticket);
-
- status = AuthenticationHelper.authenticate(context, request, response, ticket);
+
+ status = AuthenticationHelper.authenticate(context, req, res, ticket);
}
else
{
- if (isGuest && description.getRequiredAuthentication() == RequiredAuthentication.guest)
+ if (isGuest)
{
if (logger.isDebugEnabled())
logger.debug("Authenticating as Guest");
-
- status = AuthenticationHelper.authenticate(context, request, response, true);
+
+ status = AuthenticationHelper.authenticate(context, req, res, true);
}
else
{
if (logger.isDebugEnabled())
logger.debug("Authenticating session");
-
- status = AuthenticationHelper.authenticate(context, request, response, false);
+
+ status = AuthenticationHelper.authenticate(context, req, res, false);
}
}
-
+
//
- // execute web script or request authorization
+ // if not authorized, redirect to login page
//
- if (status != null && status != AuthenticationStatus.Failure)
- {
- retVal = invocation.proceed();
- }
- else
+ if (status == null || status == AuthenticationStatus.Failure)
{
// authentication failed - now need to display the login page to the user, if asked to
if (logger.isDebugEnabled())
logger.debug("Redirecting to Alfresco Login");
-
- BaseServlet.redirectToLoginPage(request, response, context);
+
+ BaseServlet.redirectToLoginPage(req, res, context);
}
}
- finally
+ catch(IOException e)
{
- if (status != null && status != AuthenticationStatus.Failure)
- {
- authenticationService.clearCurrentSecurityContext();
- if (currentUser != null)
- {
- AuthenticationUtil.setCurrentUser(currentUser);
- }
-
- if (logger.isDebugEnabled())
- logger.debug("Authentication reset: " + (currentUser == null ? "unauthenticated" : "authenticated as " + currentUser));
- }
+ throw new WebScriptException("Failed to authenticate", e);
}
-
- return retVal;
}
}
diff --git a/source/java/org/alfresco/web/scripts/WebScriptLogger.java b/source/java/org/alfresco/web/scripts/WebScriptLogger.java
deleted file mode 100644
index 46b2e05a51..0000000000
--- a/source/java/org/alfresco/web/scripts/WebScriptLogger.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2005-2007 Alfresco Software Limited.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
- * As a special exception to the terms and conditions of version 2.0 of
- * the GPL, you may redistribute this Program in connection with Free/Libre
- * and Open Source Software ("FLOSS") applications as described in Alfresco's
- * FLOSS exception. You should have recieved a copy of the text describing
- * the FLOSS exception, and it is also available here:
- * http://www.alfresco.com/legal/licensing"
- */
-package org.alfresco.web.scripts;
-
-import org.alfresco.i18n.I18NUtil;
-import org.alfresco.repo.security.authentication.AuthenticationUtil;
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-
-/**
- * Web Script Logger
- *
- * @author davidc
- */
-public class WebScriptLogger implements MethodInterceptor
-{
- // Logger
- private static final Log logger = LogFactory.getLog(WebScriptLogger.class);
-
- /* (non-Javadoc)
- * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
- */
- public Object invoke(MethodInvocation invocation)
- throws Throwable
- {
- Object retVal = null;
-
- if (logger.isDebugEnabled())
- {
- WebScript service = (WebScript)invocation.getThis();
- WebScriptDescription description = service.getDescription();
- String user = AuthenticationUtil.getCurrentUserName();
- String locale = I18NUtil.getLocale().toString();
- logger.debug("Invoking Web Script " + description.getId() + (user == null ? " (unauthenticated)" : " (authenticated as " + user + ")" + " (" + locale + ")"));
- long start = System.currentTimeMillis();
- retVal = invocation.proceed();
- long end = System.currentTimeMillis();
- logger.debug("Web Script " + description.getId() + " executed in " + (end - start) + "ms");
- }
- else
- {
- retVal = invocation.proceed();
- }
-
- return retVal;
- }
-
-}
diff --git a/source/java/org/alfresco/web/scripts/WebScriptRuntime.java b/source/java/org/alfresco/web/scripts/WebScriptRuntime.java
new file mode 100644
index 0000000000..d256338aca
--- /dev/null
+++ b/source/java/org/alfresco/web/scripts/WebScriptRuntime.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2005-2007 Alfresco Software Limited.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ * As a special exception to the terms and conditions of version 2.0 of
+ * the GPL, you may redistribute this Program in connection with Free/Libre
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's
+ * FLOSS exception. You should have recieved a copy of the text describing
+ * the FLOSS exception, and it is also available here:
+ * http://www.alfresco.com/legal/licensing"
+ */
+package org.alfresco.web.scripts;
+
+import java.io.IOException;
+
+import org.alfresco.i18n.I18NUtil;
+import org.alfresco.repo.security.authentication.AuthenticationUtil;
+import org.alfresco.repo.transaction.TransactionUtil;
+import org.alfresco.service.transaction.TransactionService;
+import org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication;
+import org.alfresco.web.scripts.WebScriptDescription.RequiredTransaction;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+/**
+ * Encapsulates the execution of a single Web Script.
+ *
+ * Provides support for logging, transactions and authentication.
+ *
+ * Sub-classes of WebScriptRuntime maintain the execution environment e.g. servlet
+ * request & response.
+ *
+ * A new instance of WebScriptRuntime is required for each new execution environment.
+ *
+ * @author davidc
+ */
+public abstract class WebScriptRuntime
+{
+ // Logger
+ protected static final Log logger = LogFactory.getLog(WebScriptRuntime.class);
+
+ /** Component Dependencies */
+ private WebScriptRegistry registry;
+ private TransactionService transactionService;
+
+ /**
+ * Construct
+ *
+ * @param registry web script registry
+ * @param transactionService transaction service
+ */
+ public WebScriptRuntime(WebScriptRegistry registry, TransactionService transactionService)
+ {
+ this.registry = registry;
+ this.transactionService = transactionService;
+ }
+
+ /**
+ * Execute the Web Script encapsulated by this Web Script Runtime
+ */
+ public void executeScript()
+ {
+ long startRuntime = System.currentTimeMillis();
+
+ String method = getScriptMethod();
+ String scriptUrl = getScriptUrl();
+
+ try
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Processing script url (" + method + ") " + scriptUrl);
+
+ WebScriptMatch match = registry.findWebScript(method, scriptUrl);
+ if (match != null)
+ {
+ // setup web script context
+ final WebScriptRequest scriptReq = createRequest(match);
+ final WebScriptResponse scriptRes = createResponse();
+
+ if (logger.isDebugEnabled())
+ logger.debug("Agent: " + scriptReq.getAgent());
+
+ long startScript = System.currentTimeMillis();
+ final WebScript script = match.getWebScript();
+ final WebScriptDescription description = script.getDescription();
+
+ try
+ {
+ if (logger.isDebugEnabled())
+ {
+ String user = AuthenticationUtil.getCurrentUserName();
+ String locale = I18NUtil.getLocale().toString();
+ logger.debug("Invoking Web Script " + description.getId() + (user == null ? " (unauthenticated)" : " (authenticated as " + user + ")" + " (" + locale + ")"));
+ }
+
+ if (description.getRequiredTransaction() == RequiredTransaction.none)
+ {
+ authenticatedExecute(scriptReq, scriptRes);
+ }
+ else
+ {
+ // encapsulate script within transaction
+ TransactionUtil.TransactionWork