diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/authcallback.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/authcallback.get.desc.xml
new file mode 100644
index 0000000000..4a67176194
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/authcallback.get.desc.xml
@@ -0,0 +1,26 @@
+
+ Authorisation Callback
+
+
+ /api/publishing/channel/{store_protocol}/{store_id}/{node_id}/authcallback
+
+ user
+ required
+ public_api
+
+
+ store_protocol
+ The protocol of the store in which the relevant publishing channel lives.
+
+
+ store_id
+ The identifier of the store in which the relevant publishing channel lives.
+
+
+ node_id
+ The identifier of the node that represents the relevant publishing channel.
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/authform.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/authform.get.desc.xml
new file mode 100644
index 0000000000..cb2db8700a
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/authform.get.desc.xml
@@ -0,0 +1,25 @@
+
+ Channel Authorisation Form
+
+ /api/publishing/channel/{store_protocol}/{store_id}/{node_id}/authform
+
+ user
+ required
+ public_api
+
+
+ store_protocol
+ The protocol of the store in which the relevant publishing channel lives.
+
+
+ store_id
+ The identifier of the store in which the relevant publishing channel lives.
+
+
+ node_id
+ The identifier of the node that represents the relevant publishing channel.
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/authform.get.html.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/authform.get.html.ftl
new file mode 100644
index 0000000000..15951c828c
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/authform.get.html.ftl
@@ -0,0 +1,23 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/authform.post.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/authform.post.desc.xml
new file mode 100644
index 0000000000..bfc817ee7e
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/authform.post.desc.xml
@@ -0,0 +1,25 @@
+
+ Channel Authorisation Form
+
+ /api/publishing/channel/{store_protocol}/{store_id}/{node_id}/authform
+
+ user
+ required
+ public_api
+
+
+ store_protocol
+ The protocol of the store in which the relevant publishing channel lives.
+
+
+ store_id
+ The identifier of the store in which the relevant publishing channel lives.
+
+
+ node_id
+ The identifier of the node that represents the relevant publishing channel.
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/authstatus.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/authstatus.get.desc.xml
new file mode 100644
index 0000000000..9bdecd5671
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/authstatus.get.desc.xml
@@ -0,0 +1,48 @@
+
+ Authorisation status check for a new publishing channel
+
+ PENDING - we haven't finished the necessary exchanges with the service provider yet.
+ REJECTED - our request to authorise the channel has been rejected. The channel creation has failed.
+ AUTHORISED - the channel has been authorised and is now ready to be used.
+
+ ]]>
+
+ /api/publishing/channel/{store_protocol}/{store_id}/{node_id}/authstatus
+
+ user
+ required
+ public_api
+
+
+ store_protocol
+ The protocol of the store in which the relevant publishing channel lives.
+
+
+ store_id
+ The identifier of the store in which the relevant publishing channel lives.
+
+
+ node_id
+ The identifier of the node that represents the relevant publishing channel.
+
+
+
+
+ json
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/authstatus.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/authstatus.get.json.ftl
new file mode 100644
index 0000000000..5619b794bf
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/authstatus.get.json.ftl
@@ -0,0 +1,10 @@
+<#-- Response to a request to check the authorisation status of a publishing channel -->
+<#escape x as jsonUtils.encodeJSONString(x)>
+{
+ "data":
+ {
+ "channelId" : "${channelId}",
+ "authStatus": "${authStatus}",
+ }
+}
+#escape>
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/channel.post.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/channel.post.desc.xml
new file mode 100644
index 0000000000..b716094636
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/channel.post.desc.xml
@@ -0,0 +1,57 @@
+
+ Create a publishing channel
+
+
+ - channelType
- mandatory - the type of delivery channel to create
+ - siteId
- mandatory - the Share site with which the new delivery channel is to be associated
+ - channelName
- mandatory - the name of the new delivery channel
+
+ Returns three pieces of informtation:
+
+
+ - channelId
- the identifier of the new publishing channel
+ - pollUrl
- The URL to poll to discover whether the channel has been authorised
+ - authoriseUrl
- The URL to send the user to in order for them to authorise access to the channel
+
+
+ ]]>
+
+ /api/publishing/channel
+
+ user
+ required
+ public_api
+
+
+ siteId
+ The id of the site to create a delivery channel on.
+
+
+ channelType
+ The identifier of the type of delivery channel to create.
+
+
+ channelName
+ The name of the channel that is to be created.
+
+
+
+
+ json
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/channel.post.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/channel.post.json.ftl
new file mode 100644
index 0000000000..5789df16e9
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/publishing/channel.post.json.ftl
@@ -0,0 +1,11 @@
+<#-- Response to a request to create a publishing channel -->
+<#escape x as jsonUtils.encodeJSONString(x)>
+{
+ "data":
+ {
+ "channelId" : "${channelId}",
+ "pollUrl": "${pollUrl}",
+ "authoriseUrl": "${authoriseUrl}"
+ }
+}
+#escape>
diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml
index 27e0625f1a..f539b3f1e3 100644
--- a/config/alfresco/web-scripts-application-context.xml
+++ b/config/alfresco/web-scripts-application-context.xml
@@ -1118,6 +1118,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
\ No newline at end of file
diff --git a/source/java/org/alfresco/repo/web/scripts/publishing/AuthCallbackWebScript.java b/source/java/org/alfresco/repo/web/scripts/publishing/AuthCallbackWebScript.java
new file mode 100644
index 0000000000..2d4da9cfb6
--- /dev/null
+++ b/source/java/org/alfresco/repo/web/scripts/publishing/AuthCallbackWebScript.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2005-2010 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+
+package org.alfresco.repo.web.scripts.publishing;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.alfresco.repo.publishing.PublishingModel;
+import org.alfresco.service.cmr.publishing.channels.Channel;
+import org.alfresco.service.cmr.publishing.channels.ChannelService;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.extensions.webscripts.AbstractWebScript;
+import org.springframework.extensions.webscripts.WebScriptRequest;
+import org.springframework.extensions.webscripts.WebScriptResponse;
+
+public class AuthCallbackWebScript extends AbstractWebScript
+{
+ private final static Log log = LogFactory.getLog(AuthCallbackWebScript.class);
+ private NodeService nodeService;
+ private ChannelService channelService;
+
+ public void setNodeService(NodeService nodeService)
+ {
+ this.nodeService = nodeService;
+ }
+
+ public void setChannelService(ChannelService channelService)
+ {
+ this.channelService = channelService;
+ }
+
+ @Override
+ public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException
+ {
+ res.setContentType("text/html");
+ res.setContentEncoding("UTF-8");
+
+ Map templateVars = req.getServiceMatch().getTemplateVars();
+ Map params = new TreeMap();
+ Map headers = new TreeMap();
+
+ for (String paramName : req.getParameterNames())
+ {
+ params.put(paramName, req.getParameterValues(paramName));
+ }
+
+ for (String header : req.getHeaderNames())
+ {
+ headers.put(header, req.getHeaderValues(header));
+ }
+
+ if (log.isDebugEnabled())
+ {
+ log.debug("templateVars = " + templateVars);
+ log.debug("params = " + params);
+ log.debug("headers = " + headers);
+ }
+
+ String channelNodeUuid = templateVars.get("node_id");
+ String channelNodeStoreProtocol = templateVars.get("store_protocol");
+ String channelNodeStoreId = templateVars.get("store_id");
+
+ NodeRef channelNodeRef = new NodeRef(channelNodeStoreProtocol, channelNodeStoreId, channelNodeUuid);
+ Channel channel = channelService.getChannel(channelNodeRef.toString());
+
+ if (channel.getChannelType().acceptAuthorisationCallback(channel, headers, params))
+ {
+ nodeService.setProperty(channelNodeRef, PublishingModel.PROP_AUTHORISATION_COMPLETE, Boolean.TRUE);
+ res.getWriter().write("Authorisation granted!");
+ }
+ else
+ {
+ Boolean authorised = (Boolean)nodeService.getProperty(channelNodeRef, PublishingModel.PROP_AUTHORISATION_COMPLETE);
+ if (authorised != null && !authorised)
+ {
+ //If we have not been granted access by the service provider then we
+ //simply delete this publishing channel
+ nodeService.deleteNode(channelNodeRef);
+ }
+ res.getWriter().write("Authorisation denied!");
+ }
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/web/scripts/publishing/AuthStatusGetWebScript.java b/source/java/org/alfresco/repo/web/scripts/publishing/AuthStatusGetWebScript.java
new file mode 100644
index 0000000000..78e857e72a
--- /dev/null
+++ b/source/java/org/alfresco/repo/web/scripts/publishing/AuthStatusGetWebScript.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2005-2010 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+
+package org.alfresco.repo.web.scripts.publishing;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.alfresco.repo.publishing.PublishingModel;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
+import org.springframework.extensions.webscripts.Cache;
+import org.springframework.extensions.webscripts.DeclarativeWebScript;
+import org.springframework.extensions.webscripts.Status;
+import org.springframework.extensions.webscripts.WebScriptRequest;
+
+public class AuthStatusGetWebScript extends DeclarativeWebScript
+{
+ private NodeService nodeService;
+
+ public void setNodeService(NodeService nodeService)
+ {
+ this.nodeService = nodeService;
+ }
+
+ @Override
+ protected Map executeImpl(WebScriptRequest req, Status status, Cache cache)
+ {
+ Map templateVars = req.getServiceMatch().getTemplateVars();
+ String channelNodeUuid = templateVars.get("node_id");
+ String channelNodeStoreProtocol = templateVars.get("store_protocol");
+ String channelNodeStoreId = templateVars.get("store_id");
+
+ String authStatus = "REJECTED";
+ NodeRef channelNodeRef = new NodeRef(channelNodeStoreProtocol, channelNodeStoreId, channelNodeUuid);
+ if (nodeService.exists(channelNodeRef))
+ {
+ Boolean authComplete = (Boolean)nodeService.getProperty(channelNodeRef, PublishingModel.PROP_AUTHORISATION_COMPLETE);
+ if (authComplete)
+ {
+ authStatus = "AUTHORISED";
+ }
+ else
+ {
+ authStatus = "PENDING";
+ }
+ }
+ Map model = new TreeMap();
+ model.put("channelId", channelNodeRef.toString());
+ model.put("authStatus", authStatus);
+
+ return model;
+ }
+}
diff --git a/source/java/org/alfresco/repo/web/scripts/publishing/ChannelPostWebScript.java b/source/java/org/alfresco/repo/web/scripts/publishing/ChannelPostWebScript.java
new file mode 100644
index 0000000000..88515dc766
--- /dev/null
+++ b/source/java/org/alfresco/repo/web/scripts/publishing/ChannelPostWebScript.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2005-2010 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+
+package org.alfresco.repo.web.scripts.publishing;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.alfresco.service.cmr.publishing.channels.Channel;
+import org.alfresco.service.cmr.publishing.channels.ChannelService;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.springframework.extensions.webscripts.Cache;
+import org.springframework.extensions.webscripts.DeclarativeWebScript;
+import org.springframework.extensions.webscripts.Status;
+import org.springframework.extensions.webscripts.WebScriptRequest;
+
+public class ChannelPostWebScript extends DeclarativeWebScript
+{
+ private ChannelService channelService;
+
+ public void setChannelService(ChannelService channelService)
+ {
+ this.channelService = channelService;
+ }
+
+ @Override
+ protected Map executeImpl(WebScriptRequest req, Status status, Cache cache)
+ {
+ String channelType = req.getParameter("channelType");
+ String siteId = req.getParameter("siteId");
+ String channelName = req.getParameter("channelName");
+
+ Channel newChannel = channelService.createChannel(siteId, channelType, channelName, null);
+
+ NodeRef channelNodeRef = newChannel.getNodeRef();
+ StringBuilder urlBuilder = new StringBuilder(req.getServerPath());
+ urlBuilder.append(req.getServiceContextPath());
+ urlBuilder.append("/api/publishing/channel/");
+ urlBuilder.append(channelNodeRef.getStoreRef().getProtocol());
+ urlBuilder.append('/');
+ urlBuilder.append(channelNodeRef.getStoreRef().getIdentifier());
+ urlBuilder.append('/');
+ urlBuilder.append(channelNodeRef.getId());
+ urlBuilder.append('/');
+
+ String baseUrl = urlBuilder.toString();
+ String pollUrl = baseUrl + "authstatus";
+ String callbackUrl = baseUrl + "authcallback";
+
+ String authoriseUrl = channelService.getChannelType(channelType).getAuthorisationUrl(newChannel, callbackUrl);
+ if (authoriseUrl == null)
+ {
+ // If a channel type returns null as the authorise URL then we
+ // assume credentials are to be supplied to us directly. We'll point the
+ // user at our own credential-gathering form.
+ authoriseUrl = baseUrl + "authform";
+ }
+
+ Map model = new TreeMap();
+ model.put("pollUrl", pollUrl);
+ model.put("authoriseUrl", authoriseUrl);
+ model.put("channelId", channelNodeRef.toString());
+
+ return model;
+ }
+}
diff --git a/source/java/org/alfresco/repo/web/scripts/publishing/PublishingRestApiTest.java b/source/java/org/alfresco/repo/web/scripts/publishing/PublishingRestApiTest.java
index 6e50e1ec23..a2d9cc15f8 100644
--- a/source/java/org/alfresco/repo/web/scripts/publishing/PublishingRestApiTest.java
+++ b/source/java/org/alfresco/repo/web/scripts/publishing/PublishingRestApiTest.java
@@ -299,12 +299,12 @@ public class PublishingRestApiTest extends BaseWebScriptTest
// Check updateStatus is called correctly.
ArgumentCaptor captor = ArgumentCaptor.forClass(String.class);
verify(statusUpdateChannelType)
- .updateStatus(captor.capture(), anyMap());
+ .updateStatus(any(Channel.class), captor.capture(), anyMap());
String actualStatusMessage = captor.getValue();
assertTrue(actualStatusMessage.startsWith(statusMessage));
verify(statusUpdateChannelType, never()).publish(any(NodeRef.class), anyMap());
- verify(publishAnyChannelType, never()).updateStatus(anyString(), anyMap());
+ verify(publishAnyChannelType, never()).updateStatus(any(Channel.class), anyString(), anyMap());
JSONObject status = json.optJSONObject(STATUS_UPDATE);
status.remove(NODE_REF);