mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Web Scripts:
- fix issues integrating with Flex (rename of tunnel url arguments) - add admin to required authentication levels - support json callback method (for browser based ajax requests) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5856 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -33,6 +33,7 @@ import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.jscript.Node;
|
||||
import org.alfresco.repo.jscript.ScriptableHashMap;
|
||||
import org.alfresco.repo.template.TemplateNode;
|
||||
@@ -132,12 +133,34 @@ public class DeclarativeWebScript extends AbstractWebScript
|
||||
{
|
||||
res.setStatus(statusCode);
|
||||
}
|
||||
res.setContentType(mimetype + ";charset=UTF-8");
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Rendering response: content type=" + mimetype + ", status=" + statusCode);
|
||||
String callback = req.getJSONCallback();
|
||||
if (format.equals(WebScriptResponse.JSON_FORMAT) && callback != null)
|
||||
{
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Rendering JSON callback response: content type=" + MimetypeMap.MIMETYPE_TEXT_JAVASCRIPT + ", status=" + statusCode + ", callback=" + callback);
|
||||
|
||||
// NOTE: special case for wrapping JSON results in a javascript function callback
|
||||
res.setContentType(MimetypeMap.MIMETYPE_TEXT_JAVASCRIPT + ";charset=UTF-8");
|
||||
res.getOutputStream().write((callback + "(").getBytes());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Rendering response: content type=" + mimetype + ", status=" + statusCode);
|
||||
|
||||
res.setContentType(mimetype + ";charset=UTF-8");
|
||||
}
|
||||
|
||||
// render response according to requested format
|
||||
renderFormatTemplate(format, templateModel, res.getWriter());
|
||||
|
||||
if (format.equals(WebScriptResponse.JSON_FORMAT) && callback != null)
|
||||
{
|
||||
// NOTE: special case for wrapping JSON results in a javascript function callback
|
||||
res.getOutputStream().write(")".getBytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Throwable e)
|
||||
|
@@ -259,6 +259,7 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
|
||||
{
|
||||
// establish static part of url template
|
||||
boolean wildcard = false;
|
||||
boolean extension = true;
|
||||
String uriTemplate = uri.getURI();
|
||||
int queryArgIdx = uriTemplate.indexOf('?');
|
||||
if (queryArgIdx != -1)
|
||||
@@ -278,6 +279,7 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
|
||||
{
|
||||
uriTemplate = uriTemplate.substring(0, extIdx);
|
||||
}
|
||||
extension = false;
|
||||
}
|
||||
|
||||
// index service by static part of url (ensuring no other service has already claimed the url)
|
||||
@@ -294,7 +296,7 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
|
||||
}
|
||||
else
|
||||
{
|
||||
URLIndex urlIndex = new URLIndex(uriTemplate, wildcard, serviceImpl);
|
||||
URLIndex urlIndex = new URLIndex(uriTemplate, wildcard, extension, serviceImpl);
|
||||
webscriptsByURL.put(uriIdx, urlIndex);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
@@ -580,13 +582,15 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
|
||||
String matchedPath = null;
|
||||
DeclarativeWebScriptMatch apiServiceMatch = null;
|
||||
String match = method.toString().toUpperCase() + ":" + uri;
|
||||
String matchNoExt = method.toString().toUpperCase() + ":" + ((uri.indexOf('.') != -1) ? uri.substring(0, uri.indexOf('.')) : uri);
|
||||
|
||||
// locate full match - on URI and METHOD
|
||||
for (Map.Entry<String, URLIndex> entry : webscriptsByURL.entrySet())
|
||||
{
|
||||
URLIndex urlIndex = entry.getValue();
|
||||
String index = entry.getKey();
|
||||
if ((urlIndex.wildcardPath && match.startsWith(index)) || (!urlIndex.wildcardPath && match.equals(index)))
|
||||
String test = urlIndex.includeExtension ? match : matchNoExt;
|
||||
if ((urlIndex.wildcardPath && test.startsWith(index)) || (!urlIndex.wildcardPath && test.equals(index)))
|
||||
{
|
||||
apiServiceMatch = new DeclarativeWebScriptMatch(urlIndex.path, urlIndex.script);
|
||||
break;
|
||||
@@ -715,15 +719,17 @@ public class DeclarativeWebScriptRegistry extends AbstractLifecycleBean
|
||||
*/
|
||||
private static class URLIndex
|
||||
{
|
||||
private URLIndex(String path, boolean wildcardPath, WebScript script)
|
||||
private URLIndex(String path, boolean wildcardPath, boolean includeExtension, WebScript script)
|
||||
{
|
||||
this.path = path;
|
||||
this.wildcardPath = wildcardPath;
|
||||
this.includeExtension = includeExtension;
|
||||
this.script = script;
|
||||
}
|
||||
|
||||
private String path;
|
||||
private boolean wildcardPath;
|
||||
private boolean includeExtension;
|
||||
private WebScript script;
|
||||
}
|
||||
|
||||
|
@@ -42,6 +42,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.repo.transaction.TransactionUtil;
|
||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.web.config.ServerConfigElement;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
@@ -62,6 +63,7 @@ public class TestWebScriptServer
|
||||
// dependencies
|
||||
protected AuthenticationService authenticationService;
|
||||
protected TransactionService transactionService;
|
||||
protected AuthorityService authorityService;
|
||||
protected DeclarativeWebScriptRegistry registry;
|
||||
protected ConfigService configService;
|
||||
|
||||
@@ -118,7 +120,15 @@ public class TestWebScriptServer
|
||||
{
|
||||
this.authenticationService = authenticationService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param authorityService
|
||||
*/
|
||||
public void setAuthorityService(AuthorityService authorityService)
|
||||
{
|
||||
this.authorityService = authorityService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Messages resource bundle
|
||||
*
|
||||
@@ -200,7 +210,7 @@ public class TestWebScriptServer
|
||||
MockHttpServletRequest req = createRequest(method, uri);
|
||||
MockHttpServletResponse res = new MockHttpServletResponse();
|
||||
|
||||
WebScriptRuntime runtime = new WebScriptServletRuntime(registry, transactionService, null, req, res, serverConfig);
|
||||
WebScriptRuntime runtime = new WebScriptServletRuntime(registry, transactionService, authorityService, null, req, res, serverConfig);
|
||||
runtime.executeScript();
|
||||
|
||||
return res;
|
||||
@@ -225,7 +235,7 @@ public class TestWebScriptServer
|
||||
}
|
||||
MockHttpServletResponse res = new MockHttpServletResponse();
|
||||
|
||||
WebScriptRuntime runtime = new WebScriptServletRuntime(registry, transactionService, null, req, res, serverConfig);
|
||||
WebScriptRuntime runtime = new WebScriptServletRuntime(registry, transactionService, authorityService, null, req, res, serverConfig);
|
||||
runtime.executeScript();
|
||||
|
||||
return res;
|
||||
|
@@ -42,7 +42,8 @@ public interface WebScriptDescription
|
||||
{
|
||||
none,
|
||||
guest,
|
||||
user
|
||||
user,
|
||||
admin
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -140,6 +140,13 @@ public interface WebScriptRequest
|
||||
* @return format style (excludes any)
|
||||
*/
|
||||
public FormatStyle getFormatStyle();
|
||||
|
||||
/**
|
||||
* Get the JSON callback method
|
||||
*
|
||||
* @return method (or null, if not specified)
|
||||
*/
|
||||
public String getJSONCallback();
|
||||
|
||||
/**
|
||||
* Get User Agent
|
||||
|
@@ -138,5 +138,13 @@ public abstract class WebScriptRequestImpl implements WebScriptRequest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.web.scripts.WebScriptRequest#getJSONCallback()
|
||||
*/
|
||||
public String getJSONCallback()
|
||||
{
|
||||
return getParameter("alf_callback");
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -28,13 +28,13 @@ import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.i18n.I18NUtil;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.transaction.TransactionUtil;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication;
|
||||
import org.alfresco.web.scripts.WebScriptDescription.RequiredTransaction;
|
||||
@@ -62,6 +62,7 @@ public abstract class WebScriptRuntime
|
||||
/** Component Dependencies */
|
||||
private WebScriptRegistry registry;
|
||||
private TransactionService transactionService;
|
||||
private AuthorityService authorityService;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
@@ -69,10 +70,11 @@ public abstract class WebScriptRuntime
|
||||
* @param registry web script registry
|
||||
* @param transactionService transaction service
|
||||
*/
|
||||
public WebScriptRuntime(WebScriptRegistry registry, TransactionService transactionService)
|
||||
public WebScriptRuntime(WebScriptRegistry registry, TransactionService transactionService, AuthorityService authorityService)
|
||||
{
|
||||
this.registry = registry;
|
||||
this.transactionService = transactionService;
|
||||
this.authorityService = authorityService;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -265,7 +267,7 @@ public abstract class WebScriptRuntime
|
||||
{
|
||||
wrappedExecute(scriptReq, scriptRes);
|
||||
}
|
||||
else if (required == RequiredAuthentication.user && isGuest)
|
||||
else if ((required == RequiredAuthentication.user || required == RequiredAuthentication.admin) && isGuest)
|
||||
{
|
||||
throw new WebScriptException(HttpServletResponse.SC_UNAUTHORIZED, "Web Script " + desc.getId() + " requires user authentication; however, a guest has attempted access.");
|
||||
}
|
||||
@@ -291,6 +293,11 @@ public abstract class WebScriptRuntime
|
||||
//
|
||||
if (authenticate(required, isGuest))
|
||||
{
|
||||
if (required == RequiredAuthentication.admin && !authorityService.hasAdminAuthority())
|
||||
{
|
||||
throw new WebScriptException(HttpServletResponse.SC_UNAUTHORIZED, "Web Script " + desc.getId() + " requires admin authentication; however, a non-admin has attempted access.");
|
||||
}
|
||||
|
||||
// Execute Web Script
|
||||
wrappedExecute(scriptReq, scriptRes);
|
||||
}
|
||||
|
@@ -33,6 +33,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.config.Config;
|
||||
import org.alfresco.config.ConfigService;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.web.config.ServerConfigElement;
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -56,6 +57,7 @@ public class WebScriptServlet extends HttpServlet
|
||||
// Component Dependencies
|
||||
private DeclarativeWebScriptRegistry registry;
|
||||
private TransactionService transactionService;
|
||||
private AuthorityService authorityService;
|
||||
private WebScriptServletAuthenticator authenticator;
|
||||
protected ConfigService configService;
|
||||
|
||||
@@ -70,6 +72,7 @@ public class WebScriptServlet extends HttpServlet
|
||||
ApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
|
||||
registry = (DeclarativeWebScriptRegistry)context.getBean("webscripts.registry");
|
||||
transactionService = (TransactionService)context.getBean("transactionComponent");
|
||||
authorityService = (AuthorityService)context.getBean("authorityServce");
|
||||
configService = (ConfigService)context.getBean("webClientConfigService");
|
||||
|
||||
// retrieve authenticator via servlet initialisation parameter
|
||||
@@ -105,7 +108,7 @@ public class WebScriptServlet extends HttpServlet
|
||||
res.setHeader("Cache-Control", "no-cache");
|
||||
res.setHeader("Pragma", "no-cache");
|
||||
|
||||
WebScriptRuntime runtime = new WebScriptServletRuntime(registry, transactionService, authenticator, req, res, serverConfig);
|
||||
WebScriptRuntime runtime = new WebScriptServletRuntime(registry, transactionService, authorityService, authenticator, req, res, serverConfig);
|
||||
runtime.executeScript();
|
||||
}
|
||||
|
||||
|
@@ -27,6 +27,7 @@ package org.alfresco.web.scripts;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.web.config.ServerConfigElement;
|
||||
import org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication;
|
||||
@@ -54,10 +55,11 @@ public class WebScriptServletRuntime extends WebScriptRuntime
|
||||
* @param req
|
||||
* @param res
|
||||
*/
|
||||
public WebScriptServletRuntime(WebScriptRegistry registry, TransactionService transactionService, WebScriptServletAuthenticator authenticator,
|
||||
public WebScriptServletRuntime(WebScriptRegistry registry, TransactionService transactionService,
|
||||
AuthorityService authorityService, WebScriptServletAuthenticator authenticator,
|
||||
HttpServletRequest req, HttpServletResponse res, ServerConfigElement serverConfig)
|
||||
{
|
||||
super(registry, transactionService);
|
||||
super(registry, transactionService, authorityService);
|
||||
this.req = req;
|
||||
this.res = res;
|
||||
this.authenticator = authenticator;
|
||||
@@ -78,13 +80,13 @@ public class WebScriptServletRuntime extends WebScriptRuntime
|
||||
String overload = req.getHeader("X-HTTP-Method-Override");
|
||||
if (overload == null || overload.length() == 0)
|
||||
{
|
||||
overload = req.getParameter("alf:method");
|
||||
overload = req.getParameter("alf_method");
|
||||
overloadParam = true;
|
||||
}
|
||||
if (overload != null && overload.length() > 0)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("POST is tunnelling method '" + overload + "' as specified by " + (overloadParam ? "alf:method parameter" : "X-HTTP-Method-Override header"));
|
||||
logger.debug("POST is tunnelling method '" + overload + "' as specified by " + (overloadParam ? "alf_method parameter" : "X-HTTP-Method-Override header"));
|
||||
|
||||
method = overload;
|
||||
}
|
||||
|
@@ -37,6 +37,7 @@ import javax.faces.event.ActionEvent;
|
||||
import javax.faces.event.FacesEvent;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.web.scripts.DeclarativeWebScriptRegistry;
|
||||
import org.alfresco.web.scripts.WebScriptMatch;
|
||||
@@ -70,6 +71,7 @@ public class UIWebScript extends SelfRenderingComponent
|
||||
|
||||
private WebScriptRegistry registry;
|
||||
private TransactionService txnService;
|
||||
private AuthorityService authorityService;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
@@ -80,6 +82,7 @@ public class UIWebScript extends SelfRenderingComponent
|
||||
FacesContext.getCurrentInstance());
|
||||
this.registry = (DeclarativeWebScriptRegistry)ctx.getBean("webscripts.registry");
|
||||
this.txnService = (TransactionService)ctx.getBean("transactionComponent");
|
||||
this.authorityService = (AuthorityService)ctx.getBean("authorityService");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -225,7 +228,7 @@ public class UIWebScript extends SelfRenderingComponent
|
||||
|
||||
WebScriptJSFRuntime(FacesContext fc, String scriptUrl)
|
||||
{
|
||||
super(registry, txnService);
|
||||
super(registry, txnService, authorityService);
|
||||
this.fc = fc;
|
||||
this.scriptUrl = scriptUrl;
|
||||
this.script = WebScriptURLRequest.splitURL(scriptUrl)[2];
|
||||
|
@@ -39,6 +39,7 @@ import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
import javax.portlet.WindowState;
|
||||
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.web.scripts.DeclarativeWebScriptRegistry;
|
||||
import org.alfresco.web.scripts.WebScript;
|
||||
@@ -73,6 +74,7 @@ public class WebScriptPortlet implements Portlet
|
||||
// Component Dependencies
|
||||
protected DeclarativeWebScriptRegistry registry;
|
||||
protected TransactionService transactionService;
|
||||
protected AuthorityService authorityService;
|
||||
protected WebScriptPortletAuthenticator authenticator;
|
||||
|
||||
|
||||
@@ -86,6 +88,7 @@ public class WebScriptPortlet implements Portlet
|
||||
WebApplicationContext ctx = (WebApplicationContext)portletCtx.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
|
||||
registry = (DeclarativeWebScriptRegistry)ctx.getBean("webscripts.registry");
|
||||
transactionService = (TransactionService)ctx.getBean("transactionComponent");
|
||||
authorityService = (AuthorityService)ctx.getBean("authorityService");
|
||||
authenticator = (WebScriptPortletAuthenticator)ctx.getBean("webscripts.authenticator.jsr168");
|
||||
}
|
||||
|
||||
@@ -209,7 +212,7 @@ public class WebScriptPortlet implements Portlet
|
||||
*/
|
||||
public WebScriptPortalRuntime(RenderRequest req, RenderResponse res, String requestUrl)
|
||||
{
|
||||
super(registry, transactionService);
|
||||
super(registry, transactionService, authorityService);
|
||||
this.req = req;
|
||||
this.res = res;
|
||||
this.requestUrlParts = WebScriptURLRequest.splitURL(requestUrl);
|
||||
|
Reference in New Issue
Block a user