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}", + } +} + 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}" + } +} + 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);