Publishing: added authorisation framework for channel types. Migrated YouTube channel type onto it, and added Twitter and SlideShare channel types. Facebook is also added, but there is an issue with the way it authorises apps, so it isn't wired in yet.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@28910 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Brian Remmington
2011-07-11 11:21:06 +00:00
parent 6ea22b4b1d
commit 761099b84e
13 changed files with 513 additions and 4 deletions

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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<String, String> templateVars = req.getServiceMatch().getTemplateVars();
Map<String,String[]> params = new TreeMap<String, String[]>();
Map<String,String[]> headers = new TreeMap<String, String[]>();
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!");
}
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache)
{
Map<String, String> 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<String,Object> model = new TreeMap<String, Object>();
model.put("channelId", channelNodeRef.toString());
model.put("authStatus", authStatus);
return model;
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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<String, Object> 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<String, Object> model = new TreeMap<String, Object>();
model.put("pollUrl", pollUrl);
model.put("authoriseUrl", authoriseUrl);
model.put("channelId", channelNodeRef.toString());
return model;
}
}

View File

@@ -299,12 +299,12 @@ public class PublishingRestApiTest extends BaseWebScriptTest
// Check updateStatus is called correctly.
ArgumentCaptor<String> 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);