diff --git a/config/alfresco/templates/webscripts/fbml.status.ftl b/config/alfresco/templates/webscripts/fbml.status.ftl
new file mode 100644
index 0000000000..9a0ba1cf2c
--- /dev/null
+++ b/config/alfresco/templates/webscripts/fbml.status.ftl
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+  |
+ Web Script Status ${status.code} - ${status.codeName} |
+
+
+
+
+ Error: | ${status.codeName} (${status.code}) - ${status.codeDescription}
+ |
+ |
Message: | ${status.message!"<Not specified>"}
+ <#if status.exception?exists>
+ |
+ <@recursestack status.exception/>
+ #if>
+ |
Server: | Alfresco ${server.edition} v${server.version} schema ${server.schema}
+ |
Time: | ${date?datetime}
+ |
+ |
+
+
+
+
+<#macro recursestack exception>
+ <#if exception.cause?exists>
+ <@recursestack exception=exception.cause/>
+ #if>
+ Exception: | ${exception.class.name}<#if exception.message?exists> - ${exception.message}#if>
+ |
|
+ <#if exception.cause?exists == false>
+ <#list exception.stackTrace as element>
+ |
| ${element}
+ #list>
+ <#else>
+ |
| ${exception.stackTrace[0]}
+ #if>
+ |
|
+#macro>
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/scriptdump.get.html.ftl b/config/alfresco/templates/webscripts/org/alfresco/scriptdump.get.html.ftl
index 804a92aabb..b1b63dde14 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/scriptdump.get.html.ftl
+++ b/config/alfresco/templates/webscripts/org/alfresco/scriptdump.get.html.ftl
@@ -24,7 +24,7 @@
|
URL Template: | ${URI} |
#list>
Format Style: | ${script.formatStyle} |
- Default Format: | ${script.defaultFormat} |
+ Default Format: | ${script.defaultFormat!"[undefined}]"} |
Implementation: | ${script_class} |
diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml
index 1141382111..ece3b74849 100644
--- a/config/alfresco/web-scripts-application-context.xml
+++ b/config/alfresco/web-scripts-application-context.xml
@@ -132,6 +132,7 @@
application/opensearchdescription+xml
text/plain
text/html
+ text/html
@@ -185,6 +186,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/source/java/org/alfresco/web/app/servlet/PageRendererServlet.java b/source/java/org/alfresco/web/app/servlet/PageRendererServlet.java
index 2086bc626b..568e21a2b4 100644
--- a/source/java/org/alfresco/web/app/servlet/PageRendererServlet.java
+++ b/source/java/org/alfresco/web/app/servlet/PageRendererServlet.java
@@ -63,6 +63,8 @@ import org.alfresco.web.scripts.WebScriptRequest;
import org.alfresco.web.scripts.WebScriptResponse;
import org.alfresco.web.scripts.WebScriptRuntime;
import org.alfresco.web.scripts.WebScriptServlet;
+import org.alfresco.web.scripts.WebScriptServletRequest;
+import org.alfresco.web.scripts.WebScriptServletResponse;
import org.alfresco.web.scripts.WebScriptURLRequest;
import org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication;
import org.apache.commons.logging.Log;
@@ -529,7 +531,7 @@ public class PageRendererServlet extends WebScriptServlet
}
@Override
- protected boolean authenticate(RequiredAuthentication required, boolean isGuest)
+ protected boolean authenticate(RequiredAuthentication required, boolean isGuest, WebScriptRequest req, WebScriptResponse res)
{
// TODO: what authentication here?
return true;
diff --git a/source/java/org/alfresco/web/scripts/AbstractWebScript.java b/source/java/org/alfresco/web/scripts/AbstractWebScript.java
index 093c933074..1d8f65b5e8 100644
--- a/source/java/org/alfresco/web/scripts/AbstractWebScript.java
+++ b/source/java/org/alfresco/web/scripts/AbstractWebScript.java
@@ -29,13 +29,11 @@ import java.io.Writer;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import javax.servlet.http.HttpServletResponse;
-import org.alfresco.repo.jscript.Scopeable;
import org.alfresco.repo.jscript.ScriptableHashMap;
import org.alfresco.repo.template.AbsoluteUrlMethod;
import org.alfresco.service.ServiceRegistry;
@@ -50,10 +48,10 @@ import org.alfresco.service.cmr.repository.TemplateService;
import org.alfresco.service.descriptor.DescriptorService;
import org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication;
import org.alfresco.web.scripts.WebScriptDescription.RequiredTransaction;
+import org.alfresco.web.scripts.facebook.FacebookModel;
+import org.alfresco.web.scripts.facebook.FacebookServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.mozilla.javascript.Context;
-import org.mozilla.javascript.Scriptable;
/**
@@ -305,14 +303,21 @@ public abstract class AbstractWebScript implements WebScript
// add web script context
model.put("args", createScriptArgs(req));
model.put("argsM", createScriptArgsM(req));
- if (req instanceof WebScriptServletRequest)
- {
- model.put("formdata", new FormData(((WebScriptServletRequest)req).getHttpServletRequest()));
- }
model.put("guest", req.isGuest());
model.put("url", new URLModel(req));
model.put("server", new ServerModel(descriptorService.getServerDescriptor()));
+ // TODO: Refactor creation of runtime specific parameters with
+ // Web Script F/W extraction
+ if (req instanceof WebScriptServletRequest)
+ {
+ model.put("formdata", ((WebScriptServletRequest)req).getFormData());
+ }
+ if (req instanceof FacebookServletRequest)
+ {
+ model.put("facebook", new FacebookModel(((FacebookServletRequest)req)));
+ }
+
// add custom model
if (customModel != null)
{
@@ -366,13 +371,20 @@ public abstract class AbstractWebScript implements WebScript
model.put("url", new URLModel(req));
model.put("webscript", getDescription());
model.put("server", new ServerModel(descriptorService.getServerDescriptor()));
-
+
+ // TODO: Refactor creation of runtime specific parameters with
+ // Web Script F/W extraction
+ if (req instanceof FacebookServletRequest)
+ {
+ model.put("facebook", new FacebookModel(((FacebookServletRequest)req)));
+ }
+
// add template support
model.put("absurl", new AbsoluteUrlMethod(req.getServerPath()));
model.put("scripturl", new ScriptUrlMethod(req, res));
model.put("clienturlfunction", new ClientUrlFunctionMethod(res));
model.put("date", new Date());
- model.put(TemplateService.KEY_IMAGE_RESOLVER, getWebScriptRegistry().getTemplateImageResolver());
+ model.put(TemplateService.KEY_IMAGE_RESOLVER, getWebScriptRegistry().getTemplateImageResolver());
// add custom model
if (customModel != null)
diff --git a/source/java/org/alfresco/web/scripts/BasicHttpAuthenticator.java b/source/java/org/alfresco/web/scripts/BasicHttpAuthenticator.java
index d3db1bac21..1c00e7937f 100644
--- a/source/java/org/alfresco/web/scripts/BasicHttpAuthenticator.java
+++ b/source/java/org/alfresco/web/scripts/BasicHttpAuthenticator.java
@@ -60,7 +60,7 @@ public class BasicHttpAuthenticator implements WebScriptServletAuthenticator
/* (non-Javadoc)
* @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
*/
- public boolean authenticate(RequiredAuthentication required, boolean isGuest, HttpServletRequest req, HttpServletResponse res)
+ public boolean authenticate(RequiredAuthentication required, boolean isGuest, WebScriptServletRequest preq, WebScriptServletResponse pres)
{
boolean authorized = false;
@@ -68,6 +68,8 @@ public class BasicHttpAuthenticator implements WebScriptServletAuthenticator
// validate credentials
//
+ HttpServletRequest req = preq.getHttpServletRequest();
+ HttpServletResponse res = pres.getHttpServletResponse();
String authorization = req.getHeader("Authorization");
String ticket = req.getParameter("alf_ticket");
diff --git a/source/java/org/alfresco/web/scripts/FormData.java b/source/java/org/alfresco/web/scripts/FormData.java
index 3f1c69a824..6e21c08e1e 100644
--- a/source/java/org/alfresco/web/scripts/FormData.java
+++ b/source/java/org/alfresco/web/scripts/FormData.java
@@ -27,7 +27,9 @@ package org.alfresco.web.scripts;
import java.io.IOException;
import java.io.Serializable;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import javax.servlet.http.HttpServletRequest;
@@ -55,8 +57,10 @@ public class FormData implements Serializable, Scopeable
private Scriptable scope;
private HttpServletRequest req;
private ServletFileUpload upload;
- private List files = null;
-
+ private Map fields = null;
+ private Map parameters = null;
+ private Map files = null;
+
/**
* Construct
*
@@ -70,24 +74,19 @@ public class FormData implements Serializable, Scopeable
/* (non-Javadoc)
* @see org.alfresco.repo.jscript.Scopeable#setScope(org.mozilla.javascript.Scriptable)
*/
- public void setScope(Scriptable scope)
- {
- this.scope = scope;
- }
-
- /**
- * Determine if multi-part form data has been provided
- *
- * @return true => multi-part
- */
- public boolean getIsMultiPart()
- {
- return upload.isMultipartContent(req);
- }
-
- public boolean jsGet_isMultipart()
+ public void setScope(Scriptable scope)
{
- return getIsMultiPart();
+ this.scope = scope;
+ }
+
+ /**
+ * Determine if multi-part form data has been provided
+ *
+ * @return true => multi-part
+ */
+ public boolean getIsMultiPart()
+ {
+ return upload.isMultipartContent(req);
}
/**
@@ -96,107 +95,143 @@ public class FormData implements Serializable, Scopeable
* @param name field to look for
* @return true => form data contains field
*/
- public boolean hasField(String name)
- {
- List files = getFiles();
- for (FileItem file : files)
- {
- if (file.getFieldName().equals(name))
- {
- return true;
- }
- }
- return false;
- }
+ public boolean hasField(String name)
+ {
+ Map fields = getFieldsMap();
+ return fields.containsKey(name);
+ }
- /**
- * Gets the Form fields
- *
- * @return array of FormField
- */
+ /**
+ * Gets the Form fields
+ *
+ * @return array of FormField
+ */
public Scriptable getFields()
{
- List files = getFiles();
- Object[] fields = new Object[files.size()];
- int i = 0;
- for (FileItem file : files)
- {
- fields[i++] = new FormField(file);
- }
+ Map fieldsMap = getFieldsMap();
+ Object[] fields = new Object[fieldsMap.values().size()];
+ fieldsMap.values().toArray(fields);
return Context.getCurrentContext().newArray(this.scope, fields);
}
- public Scriptable jsGet_fields()
+ /*package*/ Map getParameters()
{
- return getFields();
+ return getParametersMap();
}
-
+
+ /*package*/ Map getFiles()
+ {
+ return getFilesMap();
+ }
+
/**
* Helper to parse servlet request form data
*
* @return parsed form data
*/
- private List getFiles()
- {
- // NOTE: This class is not thread safe - it is expected to be constructed on each thread.
- if (files == null)
- {
- FileItemFactory factory = new DiskFileItemFactory();
- upload = new ServletFileUpload(factory);
- try
- {
- files = upload.parseRequest(req);
- }
+ private Map getFieldsMap()
+ {
+ // NOTE: This class is not thread safe - it is expected to be constructed on each thread.
+ if (fields == null)
+ {
+ FileItemFactory factory = new DiskFileItemFactory();
+ upload = new ServletFileUpload(factory);
+ try
+ {
+ List fileItems = upload.parseRequest(req);
+ fields = new HashMap();
+ for (FileItem fileItem : fileItems)
+ {
+ FormField formField = new FormField(fileItem);
+ fields.put(fileItem.getFieldName(), formField);
+ }
+ }
catch(FileUploadException e)
{
// NOTE: assume no files can be located
- files = Collections.EMPTY_LIST;
+ fields = Collections.emptyMap();
}
- }
- return files;
- }
+ }
+ return fields;
+ }
+ private Map getParametersMap()
+ {
+ if (parameters == null)
+ {
+ Map fields = getFieldsMap();
+ parameters = new HashMap();
+ for (Map.Entry entry : fields.entrySet())
+ {
+ FormField field = entry.getValue();
+ if (!field.getIsFile())
+ {
+ parameters.put(entry.getKey(), field.getValue());
+ }
+ }
+ }
+ return parameters;
+ }
+
+ private Map getFilesMap()
+ {
+ if (files == null)
+ {
+ Map fields = getFieldsMap();
+ files = new HashMap();
+ for (Map.Entry entry : fields.entrySet())
+ {
+ FormField field = entry.getValue();
+ if (field.getIsFile())
+ {
+ files.put(entry.getKey(), field.getContent());
+ }
+ }
+ }
+ return files;
+ }
+
- /**
- * Form Field
- *
- * @author davidc
- */
- public class FormField implements Serializable
- {
- private FileItem file;
+ /**
+ * Form Field
+ *
+ * @author davidc
+ */
+ public class FormField implements Serializable
+ {
+ private FileItem file;
- /**
- * Construct
- *
- * @param file
- */
- public FormField(FileItem file)
- {
- this.file = file;
- }
-
- /**
- * @return field name
- */
- public String getName()
- {
- return file.getFieldName();
- }
-
- public String jsGet_name()
- {
- return getName();
- }
-
- /**
- * @return true => field represents a file
- */
- public boolean getIsFile()
- {
- return !file.isFormField();
- }
-
+ /**
+ * Construct
+ *
+ * @param file
+ */
+ public FormField(FileItem file)
+ {
+ this.file = file;
+ }
+
+ /**
+ * @return field name
+ */
+ public String getName()
+ {
+ return file.getFieldName();
+ }
+
+ public String jsGet_name()
+ {
+ return getName();
+ }
+
+ /**
+ * @return true => field represents a file
+ */
+ public boolean getIsFile()
+ {
+ return !file.isFormField();
+ }
+
public boolean jsGet_isFile()
{
return getIsFile();
@@ -206,9 +241,9 @@ public class FormData implements Serializable, Scopeable
* @return field value (for file, attempts conversion to string)
*/
public String getValue()
- {
- return file.getString();
- }
+ {
+ return file.getString();
+ }
public String jsGet_value()
{
@@ -218,30 +253,30 @@ public class FormData implements Serializable, Scopeable
/**
* @return field as content
*/
- public ScriptContent getContent()
- {
- try
- {
- return new ScriptNode.ScriptContentStream(file.getInputStream(), getMimetype(), null);
- }
- catch(IOException e)
- {
- return null;
- }
- }
+ public ScriptContent getContent()
+ {
+ try
+ {
+ return new ScriptNode.ScriptContentStream(file.getInputStream(), getMimetype(), null);
+ }
+ catch(IOException e)
+ {
+ return null;
+ }
+ }
- public ScriptContent jsGet_content()
+ public ScriptContent jsGet_content()
{
return getContent();
}
- /**
- * @return mimetype
- */
- public String getMimetype()
- {
- return file.getContentType();
- }
+ /**
+ * @return mimetype
+ */
+ public String getMimetype()
+ {
+ return file.getContentType();
+ }
public String jsGet_mimetype()
{
@@ -251,16 +286,16 @@ public class FormData implements Serializable, Scopeable
/**
* @return filename (only for file fields, otherwise null)
*/
- public String getFilename()
- {
- return file.getName();
- }
-
+ public String getFilename()
+ {
+ return file.getName();
+ }
+
public String jsGet_filename()
{
return getFilename();
}
- }
-
+ }
+
}
diff --git a/source/java/org/alfresco/web/scripts/WebClientAuthenticator.java b/source/java/org/alfresco/web/scripts/WebClientAuthenticator.java
index bcf09e7503..2f3d463cd1 100644
--- a/source/java/org/alfresco/web/scripts/WebClientAuthenticator.java
+++ b/source/java/org/alfresco/web/scripts/WebClientAuthenticator.java
@@ -63,7 +63,7 @@ public class WebClientAuthenticator implements WebScriptServletAuthenticator, Se
/* (non-Javadoc)
* @see org.alfresco.web.scripts.WebScriptServletAuthenticator#authenticate(org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication, boolean, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
- public boolean authenticate(RequiredAuthentication required, boolean isGuest, HttpServletRequest req, HttpServletResponse res)
+ public boolean authenticate(RequiredAuthentication required, boolean isGuest, WebScriptServletRequest preq, WebScriptServletResponse pres)
{
AuthenticationStatus status = null;
@@ -72,6 +72,8 @@ public class WebClientAuthenticator implements WebScriptServletAuthenticator, Se
//
// validate credentials
//
+ HttpServletRequest req = preq.getHttpServletRequest();
+ HttpServletResponse res = pres.getHttpServletResponse();
String ticket = req.getParameter("ticket");
if (logger.isDebugEnabled())
diff --git a/source/java/org/alfresco/web/scripts/WebScriptRuntime.java b/source/java/org/alfresco/web/scripts/WebScriptRuntime.java
index a921c429b2..3a9d266143 100644
--- a/source/java/org/alfresco/web/scripts/WebScriptRuntime.java
+++ b/source/java/org/alfresco/web/scripts/WebScriptRuntime.java
@@ -25,6 +25,8 @@
package org.alfresco.web.scripts;
import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@@ -162,6 +164,13 @@ public abstract class WebScriptRuntime
{
if (logger.isInfoEnabled())
logger.info("Caught exception & redirecting to status template: " + e.getMessage());
+ if (logger.isDebugEnabled())
+ {
+ StringWriter writer = new StringWriter();
+ PrintWriter printWriter = new PrintWriter(writer);
+ e.printStackTrace(printWriter);
+ logger.debug("Caught exception: " + writer.toString());
+ }
// extract status code, if specified
int statusCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
@@ -189,10 +198,10 @@ public abstract class WebScriptRuntime
// NOTE: search order...
// 1) root located .ftl
// 2) root located status.ftl
- String templatePath = "/" + statusCode + ".ftl";
+ String templatePath = getStatusCodeTemplate(statusCode);
if (!registry.getTemplateProcessor().hasTemplate(templatePath))
{
- templatePath = "/status.ftl";
+ templatePath = getStatusTemplate();
if (!registry.getTemplateProcessor().hasTemplate(templatePath))
{
throw new WebScriptException("Failed to find status template " + templatePath + " (format: " + WebScriptResponse.HTML_FORMAT + ")");
@@ -273,7 +282,7 @@ public abstract class WebScriptRuntime
//
// Apply appropriate authentication to Web Script invocation
//
- if (authenticate(required, isGuest))
+ if (authenticate(required, isGuest, scriptReq, scriptRes))
{
if (required == RequiredAuthentication.admin && !authorityService.hasAdminAuthority())
{
@@ -404,7 +413,8 @@ public abstract class WebScriptRuntime
*
* @return true if authorised, false otherwise
*/
- protected abstract boolean authenticate(RequiredAuthentication required, boolean isGuest);
+ // TODO: DC - This method to be refactored during Web Script F/W extraction
+ protected abstract boolean authenticate(RequiredAuthentication required, boolean isGuest, WebScriptRequest req, WebScriptResponse res);
/**
* Pre-execution hook
@@ -429,4 +439,15 @@ public abstract class WebScriptRuntime
protected void postExecute(WebScriptRequest scriptReq, WebScriptResponse scriptRes)
{
}
+
+ protected String getStatusCodeTemplate(int statusCode)
+ {
+ return "/" + statusCode + ".ftl";
+ }
+
+ protected String getStatusTemplate()
+ {
+ return "/status.ftl";
+ }
+
}
diff --git a/source/java/org/alfresco/web/scripts/WebScriptServlet.java b/source/java/org/alfresco/web/scripts/WebScriptServlet.java
index 45413436de..1ac920e912 100644
--- a/source/java/org/alfresco/web/scripts/WebScriptServlet.java
+++ b/source/java/org/alfresco/web/scripts/WebScriptServlet.java
@@ -76,7 +76,7 @@ public class WebScriptServlet extends HttpServlet
String authenticatorId = getInitParameter("authenticator");
if (authenticatorId == null || authenticatorId.length() == 0)
{
- authenticatorId = "webscripts.authenticator.webclient";
+ authenticatorId = getDefaultAuthenticator();
}
Object bean = context.getBean(authenticatorId);
if (bean == null || !(bean instanceof WebScriptServletAuthenticator))
@@ -88,6 +88,9 @@ public class WebScriptServlet extends HttpServlet
// retrieve host server configuration
Config config = configService.getConfig("Server");
serverConfig = (ServerConfigElement)config.getConfigElement(ServerConfigElement.CONFIG_ELEMENT_ID);
+
+ // servlet specific initialisation
+ initServlet(context);
}
@@ -106,4 +109,21 @@ public class WebScriptServlet extends HttpServlet
runtime.executeScript();
}
+ /**
+ * Servlet specific initialisation
+ *
+ * @param context
+ */
+ protected void initServlet(ApplicationContext context)
+ {
+ // NOOP
+ }
+
+ /**
+ * @return default authenticator (bean name)
+ */
+ protected String getDefaultAuthenticator()
+ {
+ return "webscripts.authenticator.webclient";
+ }
}
diff --git a/source/java/org/alfresco/web/scripts/WebScriptServletAuthenticator.java b/source/java/org/alfresco/web/scripts/WebScriptServletAuthenticator.java
index 98099025d9..093954f25d 100644
--- a/source/java/org/alfresco/web/scripts/WebScriptServletAuthenticator.java
+++ b/source/java/org/alfresco/web/scripts/WebScriptServletAuthenticator.java
@@ -24,9 +24,6 @@
*/
package org.alfresco.web.scripts;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
import org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication;
/**
@@ -46,5 +43,6 @@ public interface WebScriptServletAuthenticator
*
* @return true if authorised to execute the script, false otherwise
*/
- public boolean authenticate(RequiredAuthentication required, boolean isGuest, HttpServletRequest req, HttpServletResponse res);
+ // TODO: DC - This method to be refactored during Web Script F/W extraction
+ public boolean authenticate(RequiredAuthentication required, boolean isGuest, WebScriptServletRequest req, WebScriptServletResponse res);
}
diff --git a/source/java/org/alfresco/web/scripts/WebScriptServletRequest.java b/source/java/org/alfresco/web/scripts/WebScriptServletRequest.java
index fd8e168386..9263afa72a 100644
--- a/source/java/org/alfresco/web/scripts/WebScriptServletRequest.java
+++ b/source/java/org/alfresco/web/scripts/WebScriptServletRequest.java
@@ -31,6 +31,8 @@ import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.alfresco.web.config.ServerConfigElement;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
/**
@@ -40,6 +42,9 @@ import org.alfresco.web.config.ServerConfigElement;
*/
public class WebScriptServletRequest extends WebScriptRequestImpl
{
+ // Logger
+ private static final Log logger = LogFactory.getLog(WebScriptServletRequest.class);
+
/** Server Config */
private ServerConfigElement serverConfig;
@@ -48,7 +53,10 @@ public class WebScriptServletRequest extends WebScriptRequestImpl
/** Service bound to this request */
private WebScriptMatch serviceMatch;
-
+
+ /** Form data associated with multipart/form-data */
+ private FormData formData;
+
/**
* Construct
@@ -56,7 +64,7 @@ public class WebScriptServletRequest extends WebScriptRequestImpl
* @param req
* @param serviceMatch
*/
- WebScriptServletRequest(HttpServletRequest req, WebScriptMatch serviceMatch)
+ public WebScriptServletRequest(HttpServletRequest req, WebScriptMatch serviceMatch)
{
this(null, req, serviceMatch);
}
@@ -68,11 +76,20 @@ public class WebScriptServletRequest extends WebScriptRequestImpl
* @param req
* @param serviceMatch
*/
- WebScriptServletRequest(ServerConfigElement serverConfig, HttpServletRequest req, WebScriptMatch serviceMatch)
+ public WebScriptServletRequest(ServerConfigElement serverConfig, HttpServletRequest req, WebScriptMatch serviceMatch)
{
this.serverConfig = serverConfig;
this.req = req;
this.serviceMatch = serviceMatch;
+ String contentType = req.getContentType();
+
+ if (logger.isDebugEnabled())
+ logger.debug("Content Type: " + contentType);
+
+ if (contentType != null && contentType.startsWith("multipart/form-data"))
+ {
+ formData = new FormData(req);
+ }
}
/**
@@ -165,10 +182,20 @@ public class WebScriptServletRequest extends WebScriptRequestImpl
*/
public String[] getParameterNames()
{
- Set keys = req.getParameterMap().keySet();
- String[] names = new String[keys.size()];
- keys.toArray(names);
- return names;
+ if (formData == null)
+ {
+ Set keys = req.getParameterMap().keySet();
+ String[] names = new String[keys.size()];
+ keys.toArray(names);
+ return names;
+ }
+ else
+ {
+ Set keys = formData.getParameters().keySet();
+ String[] names = new String[keys.size()];
+ keys.toArray(names);
+ return names;
+ }
}
/* (non-Javadoc)
@@ -176,7 +203,14 @@ public class WebScriptServletRequest extends WebScriptRequestImpl
*/
public String getParameter(String name)
{
- return req.getParameter(name);
+ if (formData == null)
+ {
+ return req.getParameter(name);
+ }
+ else
+ {
+ return formData.getParameters().get(name);
+ }
}
/* (non-Javadoc)
@@ -184,7 +218,15 @@ public class WebScriptServletRequest extends WebScriptRequestImpl
*/
public String[] getParameterValues(String name)
{
- return req.getParameterValues(name);
+ if (formData == null)
+ {
+ return req.getParameterValues(name);
+ }
+ else
+ {
+ String value = formData.getParameters().get(name);
+ return (value == null ) ? new String[] {} : new String[] {value};
+ }
}
/* (non-Javadoc)
@@ -302,4 +344,14 @@ public class WebScriptServletRequest extends WebScriptRequestImpl
return Boolean.valueOf(forceSuccess);
}
+ /**
+ * Gets the Form data associated with this request
+ *
+ * @return form data, or null if request is not multipart/form-data encoded
+ */
+ public FormData getFormData()
+ {
+ return formData;
+ }
+
}
diff --git a/source/java/org/alfresco/web/scripts/WebScriptServletRuntime.java b/source/java/org/alfresco/web/scripts/WebScriptServletRuntime.java
index b91a20b66f..f4fff0112a 100644
--- a/source/java/org/alfresco/web/scripts/WebScriptServletRuntime.java
+++ b/source/java/org/alfresco/web/scripts/WebScriptServletRuntime.java
@@ -42,10 +42,10 @@ import org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication;
*/
public class WebScriptServletRuntime extends WebScriptRuntime
{
- private HttpServletRequest req;
- private HttpServletResponse res;
- private WebScriptServletAuthenticator authenticator;
- private ServerConfigElement serverConfig;
+ protected HttpServletRequest req;
+ protected HttpServletResponse res;
+ protected WebScriptServletAuthenticator authenticator;
+ protected ServerConfigElement serverConfig;
/**
@@ -137,12 +137,12 @@ public class WebScriptServletRuntime extends WebScriptRuntime
* @see org.alfresco.web.scripts.WebScriptRuntime#authenticate(org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication, boolean)
*/
@Override
- protected boolean authenticate(RequiredAuthentication required, boolean isGuest)
+ protected boolean authenticate(RequiredAuthentication required, boolean isGuest, WebScriptRequest req, WebScriptResponse res)
{
boolean authorised = true;
if (authenticator != null)
{
- authorised = authenticator.authenticate(required, isGuest, req, res);
+ authorised = authenticator.authenticate(required, isGuest, (WebScriptServletRequest)req, (WebScriptServletResponse)res);
}
return authorised;
}
diff --git a/source/java/org/alfresco/web/scripts/facebook/FacebookAPIRuntime.java b/source/java/org/alfresco/web/scripts/facebook/FacebookAPIRuntime.java
new file mode 100644
index 0000000000..2407a3167d
--- /dev/null
+++ b/source/java/org/alfresco/web/scripts/facebook/FacebookAPIRuntime.java
@@ -0,0 +1,71 @@
+/*
+ * 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.facebook;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.alfresco.service.ServiceRegistry;
+import org.alfresco.web.config.ServerConfigElement;
+import org.alfresco.web.scripts.WebScriptMatch;
+import org.alfresco.web.scripts.WebScriptRegistry;
+import org.alfresco.web.scripts.WebScriptRequest;
+import org.alfresco.web.scripts.WebScriptServletAuthenticator;
+import org.alfresco.web.scripts.WebScriptServletRuntime;
+
+
+/**
+ * HTTP Servlet Web Script Runtime
+ *
+ * @author davidc
+ */
+public class FacebookAPIRuntime extends WebScriptServletRuntime
+{
+
+ /**
+ * Construct
+ *
+ * @param registry
+ * @param serviceRegistry
+ * @param authenticator
+ * @param req
+ * @param res
+ */
+ public FacebookAPIRuntime(WebScriptRegistry registry, ServiceRegistry serviceRegistry, WebScriptServletAuthenticator authenticator,
+ HttpServletRequest req, HttpServletResponse res, ServerConfigElement serverConfig)
+ {
+ super(registry, serviceRegistry, authenticator, req, res, serverConfig);
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.web.scripts.WebScriptRuntime#createRequest(org.alfresco.web.scripts.WebScriptMatch)
+ */
+ @Override
+ protected WebScriptRequest createRequest(WebScriptMatch match)
+ {
+ return new FacebookServletRequest(serverConfig, req, match, getScriptUrl());
+ }
+
+}
diff --git a/source/java/org/alfresco/web/scripts/facebook/FacebookAPIServlet.java b/source/java/org/alfresco/web/scripts/facebook/FacebookAPIServlet.java
new file mode 100644
index 0000000000..fc8b2064c5
--- /dev/null
+++ b/source/java/org/alfresco/web/scripts/facebook/FacebookAPIServlet.java
@@ -0,0 +1,76 @@
+/*
+ * 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.facebook;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.alfresco.web.scripts.WebScriptRuntime;
+import org.alfresco.web.scripts.WebScriptServlet;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+/**
+ * Web Script API entry point (with Facebook authentication)
+ *
+ * @author davidc
+ */
+public class FacebookAPIServlet extends WebScriptServlet
+{
+ private static final long serialVersionUID = 4209892938069597860L;
+
+ // Logger
+ private static final Log logger = LogFactory.getLog(FacebookAPIServlet.class);
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest,
+ * javax.servlet.http.HttpServletResponse)
+ */
+ protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Processing facebook api request (" + req.getMethod() + ") " + req.getRequestURL() + (req.getQueryString() != null ? "?" + req.getQueryString() : ""));
+
+ WebScriptRuntime runtime = new FacebookAPIRuntime(registry, serviceRegistry, authenticator, req, res, serverConfig);
+ runtime.executeScript();
+ }
+
+ /**
+ * @return default authenticator (bean name)
+ */
+ @Override
+ protected String getDefaultAuthenticator()
+ {
+ return "facebook.authenticator";
+ }
+
+}
diff --git a/source/java/org/alfresco/web/scripts/facebook/FacebookAppModel.java b/source/java/org/alfresco/web/scripts/facebook/FacebookAppModel.java
new file mode 100644
index 0000000000..c32c00083a
--- /dev/null
+++ b/source/java/org/alfresco/web/scripts/facebook/FacebookAppModel.java
@@ -0,0 +1,40 @@
+package org.alfresco.web.scripts.facebook;
+
+public class FacebookAppModel
+{
+ String appId;
+ String apiKey;
+ String secretKey;
+
+
+ public FacebookAppModel(String apiKey)
+ {
+ this.apiKey = apiKey;
+ }
+
+ public String getApiKey()
+ {
+ return apiKey;
+ }
+
+ public String getSecret()
+ {
+ return secretKey;
+ }
+
+ public void setSecret(String secretKey)
+ {
+ this.secretKey = secretKey;
+ }
+
+ public String getId()
+ {
+ return appId;
+ }
+
+ public void setId(String appId)
+ {
+ this.appId = appId;
+ }
+
+}
diff --git a/source/java/org/alfresco/web/scripts/facebook/FacebookAuthenticator.java b/source/java/org/alfresco/web/scripts/facebook/FacebookAuthenticator.java
new file mode 100644
index 0000000000..e2a19c4020
--- /dev/null
+++ b/source/java/org/alfresco/web/scripts/facebook/FacebookAuthenticator.java
@@ -0,0 +1,102 @@
+/*
+ * 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.facebook;
+
+import java.io.IOException;
+
+import org.alfresco.repo.security.authentication.AuthenticationUtil;
+import org.alfresco.web.scripts.WebScriptException;
+import org.alfresco.web.scripts.WebScriptServletAuthenticator;
+import org.alfresco.web.scripts.WebScriptServletRequest;
+import org.alfresco.web.scripts.WebScriptServletResponse;
+import org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+public class FacebookAuthenticator implements WebScriptServletAuthenticator
+{
+ // Logger
+ private static final Log logger = LogFactory.getLog(FacebookAuthenticator.class);
+
+ // FBML for Facebook login redirect
+ private static final String LOGIN_REDIRECT = "";
+
+
+ /* (non-Javadoc)
+ * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
+ */
+ public boolean authenticate(RequiredAuthentication required, boolean isGuest, WebScriptServletRequest req, WebScriptServletResponse res)
+ {
+ // TODO: Refactor with Web Script F/W Extraction
+ FacebookServletRequest fbreq = (FacebookServletRequest)req;
+
+ String sessionKey = fbreq.getSessionKey();
+ String user = fbreq.getUserId();
+
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("fb_sig_session_key = '" + sessionKey + "'");
+ logger.debug("fb_sig_user = '" + user + "'");
+ }
+
+ if ((sessionKey == null || sessionKey.length() == 0) || (user == null || user.length() == 0))
+ {
+ // session has not been established, redirect to login
+
+ String apiKey = fbreq.getApiKey();
+ String canvas = (fbreq.isInCanvas()) ? "&canvas" : "";
+
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("fb_sig_api_key = '" + apiKey + "'");
+ logger.debug("fb_sig_in_canvas = '" + canvas + "'");
+ }
+
+ try
+ {
+ String redirect = String.format(LOGIN_REDIRECT, apiKey, canvas);
+
+ if (logger.isDebugEnabled())
+ logger.debug("Facebook session not established; redirecting via " + redirect);
+
+ res.getWriter().write(redirect);
+ }
+ catch (IOException e)
+ {
+ throw new WebScriptException("Redirect to login failed", e);
+ }
+ return false;
+ }
+
+ if (logger.isDebugEnabled())
+ logger.debug("Facebook session established; authenticating as user " + user);
+
+ // session has been established, authenticate as Facebook user id
+ AuthenticationUtil.setCurrentUser(user);
+ return true;
+ }
+
+}
diff --git a/source/java/org/alfresco/web/scripts/facebook/FacebookModel.java b/source/java/org/alfresco/web/scripts/facebook/FacebookModel.java
new file mode 100644
index 0000000000..05fce4468c
--- /dev/null
+++ b/source/java/org/alfresco/web/scripts/facebook/FacebookModel.java
@@ -0,0 +1,133 @@
+package org.alfresco.web.scripts.facebook;
+
+import java.io.IOException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+
+import com.facebook.api.FacebookException;
+import com.facebook.api.FacebookRestClient;
+
+
+public class FacebookModel
+{
+ // Logger
+ private static final Log logger = LogFactory.getLog(FacebookModel.class);
+
+ private FacebookServletRequest req;
+ private FacebookRestClient client;
+ private String[] friends;
+
+ public FacebookModel(FacebookServletRequest req)
+ {
+ this.req = req;
+ }
+
+ private FacebookRestClient getClient()
+ {
+ if (client == null)
+ {
+ String apiKey = req.getApiKey();
+ String secretKey = req.getSecretKey();
+ String sessionKey = req.getSessionKey();
+ if (sessionKey == null)
+ {
+ client = new FacebookRestClient(apiKey, secretKey);
+ }
+ else
+ {
+ client = new FacebookRestClient(apiKey, secretKey, sessionKey);
+ }
+ }
+ return client;
+ }
+
+ public String[] getFriends()
+ {
+ if (friends == null)
+ {
+ friends = req.getFriends();
+ if (friends == null)
+ {
+ try
+ {
+ Document friendsDoc = getClient().friends_get();
+ NodeList uids = friendsDoc.getElementsByTagName("uid");
+ friends = new String[uids.getLength()];
+ for (int i = 0; i < uids.getLength(); i++)
+ {
+ friends[i] = uids.item(i).getTextContent();
+ }
+ }
+ catch(Exception e)
+ {
+ friends = new String[0];
+ }
+ }
+ }
+ return friends;
+ }
+
+ public String getUser()
+ {
+ return req.getUserId();
+ }
+
+ public String getAppId()
+ {
+ return req.getAppId();
+ }
+
+ public String getSessionKey()
+ {
+ return req.getSessionKey();
+ }
+
+ public String getApiKey()
+ {
+ return req.getApiKey();
+ }
+
+ public String getCanvasPath()
+ {
+ return req.getCanvasPath();
+ }
+
+ public String getCanvasURL()
+ {
+ return "http://apps.facebook.com/" + getCanvasPath();
+ }
+
+ public String getPageURL()
+ {
+ return "http://apps.facebook.com" + req.getPathInfo();
+ }
+
+ public String getSecret()
+ {
+ return req.getSecretKey();
+ }
+
+ public boolean postUserAction(String title, String body)
+ {
+ try
+ {
+ Document result = getClient().feed_publishActionOfUser(title, body);
+ // TODO: check result
+ return true;
+ }
+ catch (FacebookException e)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Failed to post user action [title=" + title + ", body=" + body + "] due to " + e.toString());
+ }
+ catch (IOException e)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Failed to post user action [title=" + title + ", body=" + body + "] due to " + e.toString());
+ }
+ return false;
+ }
+}
diff --git a/source/java/org/alfresco/web/scripts/facebook/FacebookService.java b/source/java/org/alfresco/web/scripts/facebook/FacebookService.java
new file mode 100644
index 0000000000..a22ddd1d45
--- /dev/null
+++ b/source/java/org/alfresco/web/scripts/facebook/FacebookService.java
@@ -0,0 +1,118 @@
+package org.alfresco.web.scripts.facebook;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.alfresco.service.cmr.repository.ScriptLocation;
+import org.alfresco.web.scripts.WebScriptContext;
+import org.alfresco.web.scripts.WebScriptException;
+import org.alfresco.web.scripts.WebScriptRegistry;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+public class FacebookService
+{
+ // Logger
+ private static final Log logger = LogFactory.getLog(FacebookService.class);
+
+ // Facebook Application Cache
+ private Map apps = new HashMap();
+ private ReentrantReadWriteLock appsLock = new ReentrantReadWriteLock();
+
+ private WebScriptRegistry registry;
+ private WebScriptContext context;
+
+
+ public void setRegistry(WebScriptRegistry registry)
+ {
+ this.registry = registry;
+ }
+
+
+
+ FacebookAppModel getAppModel(String apiKey)
+ {
+ FacebookAppModel facebookApp = null;
+ appsLock.readLock().lock();
+
+ try
+ {
+ facebookApp = apps.get(apiKey);
+ if (facebookApp == null)
+ {
+ // Upgrade read lock to write lock
+ appsLock.readLock().unlock();
+ appsLock.writeLock().lock();
+
+ try
+ {
+ // Check again
+ facebookApp = apps.get(apiKey);
+ if (facebookApp == null)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Initialising Facebook Application '" + apiKey + "'");
+
+ // Locate app initialisation script in web script store
+ String appPath = "/com/facebook/_apps/app." + apiKey + ".js";
+ ScriptLocation appScript = registry.getScriptProcessor().findScript(appPath);
+ if (appScript == null)
+ {
+ throw new WebScriptException("Unable to locate application initialisation script '" + appPath + "'");
+ }
+
+ // Execute app initialisation script
+ Map model = new HashMap();
+ FacebookAppModel app = new FacebookAppModel(apiKey);
+ model.put("app", app);
+ registry.getScriptProcessor().executeScript(appScript, model);
+
+ // Validate initialisation
+ if (app.getSecret() == null)
+ {
+ throw new WebScriptException("Secret key for application '" + apiKey + "' has not been specified.");
+ }
+ if (app.getApiKey() == null)
+ {
+ throw new WebScriptException("Application Id for application '" + apiKey + "' has not been specified.");
+ }
+
+ apps.put(apiKey, app);
+ facebookApp = app;
+ }
+ }
+ finally
+ {
+ // Downgrade lock to read
+ appsLock.readLock().lock();
+ appsLock.writeLock().unlock();
+ }
+ }
+ return facebookApp;
+ }
+ finally
+ {
+ appsLock.readLock().unlock();
+ }
+ }
+
+ public Map getAppModels()
+ {
+ return apps;
+ }
+
+ public void reset()
+ {
+ appsLock.writeLock().lock();
+ try
+ {
+ apps.clear();
+ }
+ finally
+ {
+ appsLock.writeLock().unlock();
+ }
+ }
+}
diff --git a/source/java/org/alfresco/web/scripts/facebook/FacebookServlet.java b/source/java/org/alfresco/web/scripts/facebook/FacebookServlet.java
new file mode 100644
index 0000000000..ce69ff7620
--- /dev/null
+++ b/source/java/org/alfresco/web/scripts/facebook/FacebookServlet.java
@@ -0,0 +1,74 @@
+/*
+ * 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.facebook;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.alfresco.web.scripts.WebScriptRuntime;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.context.ApplicationContext;
+
+
+/**
+ * Facebook Canvas Page Requests
+ *
+ * @author davidc
+ */
+public class FacebookServlet extends FacebookAPIServlet
+{
+ // Logger
+ private static final Log logger = LogFactory.getLog(FacebookServlet.class);
+
+ // Component Dependencies
+ protected FacebookService facebookService;
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest,
+ * javax.servlet.http.HttpServletResponse)
+ */
+ protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Processing facebook canvas (" + req.getMethod() + ") " + req.getRequestURL() + (req.getQueryString() != null ? "?" + req.getQueryString() : ""));
+
+ WebScriptRuntime runtime = new FacebookServletRuntime(registry, serviceRegistry, authenticator, req, res, serverConfig, facebookService);
+ runtime.executeScript();
+ }
+
+ @Override
+ protected void initServlet(ApplicationContext context)
+ {
+ facebookService = (FacebookService)context.getBean("facebook.service");
+ }
+
+}
diff --git a/source/java/org/alfresco/web/scripts/facebook/FacebookServletRequest.java b/source/java/org/alfresco/web/scripts/facebook/FacebookServletRequest.java
new file mode 100644
index 0000000000..d92c7f9a84
--- /dev/null
+++ b/source/java/org/alfresco/web/scripts/facebook/FacebookServletRequest.java
@@ -0,0 +1,125 @@
+/*
+ * 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.facebook;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.alfresco.web.config.ServerConfigElement;
+import org.alfresco.web.scripts.WebScriptException;
+import org.alfresco.web.scripts.WebScriptMatch;
+import org.alfresco.web.scripts.WebScriptServletRequest;
+
+
+/**
+ * HTTP Servlet Web Script Request
+ *
+ * @author davidc
+ */
+public class FacebookServletRequest extends WebScriptServletRequest
+{
+ private String appId;
+ private String secretKey;
+ private String pathInfo;
+
+
+ /**
+ * Construct
+ *
+ * @param serverConfig
+ * @param req
+ * @param serviceMatch
+ */
+ public FacebookServletRequest(ServerConfigElement serverConfig, HttpServletRequest req, WebScriptMatch serviceMatch, String pathInfo)
+ {
+ super(serverConfig, req, serviceMatch);
+ this.pathInfo = pathInfo;
+ }
+
+ /*package*/ void setSecretKey(String secretKey)
+ {
+ this.secretKey = secretKey;
+ }
+
+ /*package*/ void setAppId(String appId)
+ {
+ this.appId = appId;
+ }
+
+ public String getApiKey()
+ {
+ return getParameter("fb_sig_api_key");
+ }
+
+ public String getUserId()
+ {
+ return getParameter("fb_sig_user");
+ }
+
+ public String getSessionKey()
+ {
+ return getParameter("fb_sig_session_key");
+ }
+
+ public boolean isInCanvas()
+ {
+ String canvas = getParameter("fb_sig_api_key");
+ return (canvas == null || canvas.equals("1"));
+ }
+
+ public String getSecretKey()
+ {
+ return secretKey;
+ }
+
+ public String getAppId()
+ {
+ return appId;
+ }
+
+ public String getCanvasPath()
+ {
+ String pathInfo = getPathInfo();
+ String[] pathSegments = pathInfo.split("/");
+ if (pathSegments.length < 3)
+ {
+ throw new WebScriptException("Cannot establish Facebook Canvas Page URL from request " + getURL());
+ }
+ return pathSegments[2];
+ }
+
+ public String[] getFriends()
+ {
+ String[] friends;
+ String friendsStr = getParameter("fb_sig_friends");
+ friends = (friendsStr == null) ? new String[0] : friendsStr.split(",");
+ return friends;
+ }
+
+ @Override
+ public String getPathInfo()
+ {
+ return pathInfo;
+ }
+}
diff --git a/source/java/org/alfresco/web/scripts/facebook/FacebookServletRuntime.java b/source/java/org/alfresco/web/scripts/facebook/FacebookServletRuntime.java
new file mode 100644
index 0000000000..21cd785060
--- /dev/null
+++ b/source/java/org/alfresco/web/scripts/facebook/FacebookServletRuntime.java
@@ -0,0 +1,107 @@
+/*
+ * 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.facebook;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.alfresco.service.ServiceRegistry;
+import org.alfresco.web.config.ServerConfigElement;
+import org.alfresco.web.scripts.WebScriptMatch;
+import org.alfresco.web.scripts.WebScriptRegistry;
+import org.alfresco.web.scripts.WebScriptRequest;
+import org.alfresco.web.scripts.WebScriptServletAuthenticator;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+/**
+ * HTTP Servlet Web Script Runtime
+ *
+ * @author davidc
+ */
+public class FacebookServletRuntime extends FacebookAPIRuntime
+{
+ // Logger
+ private static final Log logger = LogFactory.getLog(FacebookServletRuntime.class);
+
+ protected FacebookService facebookService;
+
+ /**
+ * Construct
+ *
+ * @param registry
+ * @param serviceRegistry
+ * @param authenticator
+ * @param req
+ * @param res
+ */
+ public FacebookServletRuntime(WebScriptRegistry registry, ServiceRegistry serviceRegistry, WebScriptServletAuthenticator authenticator,
+ HttpServletRequest req, HttpServletResponse res, ServerConfigElement serverConfig, FacebookService facebookService)
+ {
+ super(registry, serviceRegistry, authenticator, req, res, serverConfig);
+ this.facebookService = facebookService;
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.web.scripts.WebScriptRuntime#createRequest(org.alfresco.web.scripts.WebScriptMatch)
+ */
+ @Override
+ protected WebScriptRequest createRequest(WebScriptMatch match)
+ {
+ FacebookServletRequest fbreq = new FacebookServletRequest(serverConfig, req, match, getScriptUrl());
+
+ if (match != null)
+ {
+ FacebookAppModel appModel = facebookService.getAppModel(fbreq.getApiKey());
+ fbreq.setSecretKey(appModel.getSecret());
+ fbreq.setAppId(appModel.getId());
+ }
+
+ if (logger.isDebugEnabled())
+ logger.debug("Facebook request [apiKey=" + fbreq.getApiKey() + ", user=" + fbreq.getUserId() + ", session=" + fbreq.getSessionKey() + ", secret=" + fbreq.getSecretKey() + "]");
+
+ return fbreq;
+ }
+
+ @Override
+ protected String getScriptUrl()
+ {
+ return "/facebook" + super.getScriptUrl();
+ }
+
+ @Override
+ protected String getStatusCodeTemplate(int statusCode)
+ {
+ return "/fbml." + statusCode + ".ftl";
+ }
+
+ @Override
+ protected String getStatusTemplate()
+ {
+ return "/fbml.status.ftl";
+ }
+
+}
diff --git a/source/java/org/alfresco/web/scripts/jsf/UIWebScript.java b/source/java/org/alfresco/web/scripts/jsf/UIWebScript.java
index 85934e4510..9bccb02316 100644
--- a/source/java/org/alfresco/web/scripts/jsf/UIWebScript.java
+++ b/source/java/org/alfresco/web/scripts/jsf/UIWebScript.java
@@ -288,7 +288,7 @@ public class UIWebScript extends SelfRenderingComponent
* @see org.alfresco.web.scripts.WebScriptRuntime#authenticate(org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication, boolean)
*/
@Override
- protected boolean authenticate(RequiredAuthentication required, boolean isGuest)
+ protected boolean authenticate(RequiredAuthentication required, boolean isGuest, WebScriptRequest req, WebScriptResponse res)
{
// JSF component already in an authenticated environment as the
// /faces servlet filter (or JSF portlet wrapper) is called first
diff --git a/source/java/org/alfresco/web/scripts/portlet/WebScriptPortlet.java b/source/java/org/alfresco/web/scripts/portlet/WebScriptPortlet.java
index fa81833b01..44abc6fd2e 100644
--- a/source/java/org/alfresco/web/scripts/portlet/WebScriptPortlet.java
+++ b/source/java/org/alfresco/web/scripts/portlet/WebScriptPortlet.java
@@ -285,7 +285,7 @@ public class WebScriptPortlet implements Portlet
* @see org.alfresco.web.scripts.WebScriptRuntime#authenticate(org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication, boolean)
*/
@Override
- protected boolean authenticate(RequiredAuthentication required, boolean isGuest)
+ protected boolean authenticate(RequiredAuthentication required, boolean isGuest, WebScriptRequest preq, WebScriptResponse pres)
{
return authenticator.authenticate(required, isGuest, req, res);
}
diff --git a/source/web/WEB-INF/web.xml b/source/web/WEB-INF/web.xml
index 1321bb398c..ef61d7dea1 100644
--- a/source/web/WEB-INF/web.xml
+++ b/source/web/WEB-INF/web.xml
@@ -277,6 +277,16 @@
org.alfresco.web.scripts.WebScriptServlet
+
+ facebookServlet
+ org.alfresco.web.scripts.facebook.FacebookServlet
+
+
+
+ fbapiServlet
+ org.alfresco.web.scripts.facebook.FacebookAPIServlet
+
+
proxyServlet
org.alfresco.web.app.servlet.HTTPProxyServlet
@@ -422,6 +432,26 @@
/168s/*
+
+ facebookServlet
+ /facebook/*
+
+
+
+ facebookServlet
+ /fb/*
+
+
+
+ fbapiServlet
+ /fbservice/*
+
+
+
+ fbapiServlet
+ /fbs/*
+
+
proxyServlet
/proxy