Publishing:

- Added reauthorisation API for publishing channels
- Refactored OAuth1 channels to share common functionality (Twitter and Flickr)

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@29362 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Brian Remmington
2011-07-26 15:42:57 +00:00
parent a3b541a7a2
commit 89e8369e38
11 changed files with 250 additions and 29 deletions

View File

@@ -0,0 +1,56 @@
<webscript>
<shortname>Reauthorise the specified publishing channel</shortname>
<description><![CDATA[
Initiate an attempt to reauthorise the specified publishing channel.
<br />
Response status may be:
<dl>
<dt>200</dt><dd>The body of the response contains the necessary information to continue the reauthorisation process</dd>
<dt>400</dt><dd>invalid data received from caller</dd>
<dt>404</dt><dd>the specified channel cannot be found</dd>
</dl>
Returns three pieces of informtation:
<br />
<dl>
<dt>channelId</dt><dd>the identifier of the publishing channel</dd>
<dt>authoriseUrl</dt> <dd>The URL to send the user to in order for them to authorise access to the channel</dd>
<dt>authCallbackUrl</dt> <dd>The URL to return the channel authorisation details to</dd>
</dl>
]]></description>
<url>/api/publishing/channels/{store_protocol}/{store_id}/{node_id}/reauthorise</url>
<format default="json"/>
<authentication>user</authentication>
<transaction>required</transaction>
<lifecycle>public_api</lifecycle>
<args>
<arg>
<shortname>store_protocol</shortname>
<description>The protocol of the store in which the relevant publishing channel lives.</description>
</arg>
<arg>
<shortname>store_id</shortname>
<description>The identifier of the store in which the relevant publishing channel lives.</description>
</arg>
<arg>
<shortname>node_id</shortname>
<description>The identifier of the node that represents the relevant publishing channel.</description>
</arg>
</args>
<responses>
<response>
<format>json</format>
<type>
<![CDATA[
{
"data":
{
"channelId": string,
"authoriseUrl": string
"authCallbackUrl": string
}
}
]]>
</type>
</response>
</responses>
</webscript>

View File

@@ -0,0 +1,6 @@
<#-- Response to a request to create a publishing channel -->
<#import "publishing.lib.ftl" as publishLib />
{
"data":
<@publishLib.channelAuthJSON />
}

View File

@@ -0,0 +1,56 @@
<webscript>
<shortname>Reauthorise the specified publishing channel</shortname>
<description><![CDATA[
Initiate an attempt to reauthorise the specified publishing channel.
<br />
Response status may be:
<dl>
<dt>200</dt><dd>The body of the response contains the necessary information to continue the reauthorisation process</dd>
<dt>400</dt><dd>invalid data received from caller</dd>
<dt>404</dt><dd>the specified channel cannot be found</dd>
</dl>
Returns three pieces of informtation:
<br />
<dl>
<dt>channelId</dt><dd>the identifier of the publishing channel</dd>
<dt>authoriseUrl</dt> <dd>The URL to send the user to in order for them to authorise access to the channel</dd>
<dt>authCallbackUrl</dt> <dd>The URL to return the channel authorisation details to</dd>
</dl>
]]></description>
<url>/api/publishing/channels/{store_protocol}/{store_id}/{node_id}/reauthorise</url>
<format default="json"/>
<authentication>user</authentication>
<transaction>required</transaction>
<lifecycle>public_api</lifecycle>
<args>
<arg>
<shortname>store_protocol</shortname>
<description>The protocol of the store in which the relevant publishing channel lives.</description>
</arg>
<arg>
<shortname>store_id</shortname>
<description>The identifier of the store in which the relevant publishing channel lives.</description>
</arg>
<arg>
<shortname>node_id</shortname>
<description>The identifier of the node that represents the relevant publishing channel.</description>
</arg>
</args>
<responses>
<response>
<format>json</format>
<type>
<![CDATA[
{
"data":
{
"channelId": string,
"authoriseUrl": string
"authCallbackUrl": string
}
}
]]>
</type>
</response>
</responses>
</webscript>

View File

@@ -0,0 +1,6 @@
<#-- Response to a request to create a publishing channel -->
<#import "publishing.lib.ftl" as publishLib />
{
"data":
<@publishLib.channelAuthJSON />
}

View File

@@ -47,7 +47,6 @@
"data": "data":
{ {
"channelId": string, "channelId": string,
"pollUrl": string,
"authoriseUrl": string "authoriseUrl": string
"authCallbackUrl": string "authCallbackUrl": string
} }

View File

@@ -1,11 +1,6 @@
<#-- Response to a request to create a publishing channel --> <#-- Response to a request to create a publishing channel -->
<#escape x as jsonUtils.encodeJSONString(x)> <#import "publishing.lib.ftl" as publishLib />
{ {
"data": "data":
{ <@publishLib.channelAuthJSON />
"channelId" : "${channelId}",
"authoriseUrl": "${authoriseUrl}",
"authCallbackUrl": "${authCallbackUrl}"
}
} }
</#escape>

View File

@@ -138,3 +138,15 @@
"timeZone": "${calendar.timeZone}" "timeZone": "${calendar.timeZone}"
} }
</#macro> </#macro>
<#-- Renders a calendar. -->
<#macro channelAuthJSON>
<#escape x as jsonUtils.encodeJSONString(x)>
{
"channelId" : "${channelId}",
"authoriseUrl": "${authoriseUrl}",
"authCallbackUrl": "${authCallbackUrl}"
}
</#escape>
</#macro>

View File

@@ -1185,6 +1185,20 @@
<property name="channelService" ref="channelService" /> <property name="channelService" ref="channelService" />
</bean> </bean>
<bean id="webscript.org.alfresco.repository.publishing.channel-reath.get"
class="org.alfresco.repo.web.scripts.publishing.ChannelReauthWebScript"
parent="webscript">
<property name="channelService" ref="channelService" />
<property name="channelAuthHelper" ref="channelAuthHelper" />
</bean>
<bean id="webscript.org.alfresco.repository.publishing.channel-reath.post"
class="org.alfresco.repo.web.scripts.publishing.ChannelReauthWebScript"
parent="webscript">
<property name="channelService" ref="channelService" />
<property name="channelAuthHelper" ref="channelAuthHelper" />
</bean>
<!-- --> <!-- -->
<!-- Audit Service REST API --> <!-- Audit Service REST API -->
<!-- --> <!-- -->

View File

@@ -18,7 +18,11 @@
*/ */
package org.alfresco.repo.web.scripts.publishing; package org.alfresco.repo.web.scripts.publishing;
import java.util.Map;
import java.util.TreeMap;
import org.alfresco.repo.admin.SysAdminParams; import org.alfresco.repo.admin.SysAdminParams;
import org.alfresco.service.cmr.publishing.channels.Channel;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.util.UrlUtil; import org.alfresco.util.UrlUtil;
@@ -60,4 +64,23 @@ public class ChannelAuthHelper
{ {
return getBaseChannelApiUrl(channelId) + "authcallback"; return getBaseChannelApiUrl(channelId) + "authcallback";
} }
public Map<String, Object> buildAuthorisationModel(Channel channel)
{
String callbackUrl = getAuthoriseCallbackUrl(channel.getNodeRef());
String authoriseUrl = channel.getChannelType().getAuthorisationUrl(channel, 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 = getDefaultAuthoriseUrl(channel.getNodeRef());
}
Map<String, Object> model = new TreeMap<String, Object>();
model.put("authoriseUrl", authoriseUrl);
model.put("channelId", channel.getId());
model.put("authCallbackUrl", callbackUrl);
return model;
}
} }

View File

@@ -0,0 +1,74 @@
/*
* 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 javax.servlet.http.HttpServletResponse;
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.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
public class ChannelReauthWebScript extends DeclarativeWebScript
{
private ChannelService channelService;
private ChannelAuthHelper channelAuthHelper;
public void setChannelService(ChannelService channelService)
{
this.channelService = channelService;
}
public void setChannelAuthHelper(ChannelAuthHelper channelAuthHelper)
{
this.channelAuthHelper = channelAuthHelper;
}
@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");
if (channelNodeStoreId == null || channelNodeStoreProtocol == null || channelNodeUuid == null)
{
throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "Missing parameter(s)");
}
NodeRef channelNodeRef = new NodeRef(channelNodeStoreProtocol, channelNodeStoreId, channelNodeUuid);
Channel channel = channelService.getChannelById(channelNodeRef.toString());
if (channel == null)
{
throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Channel not found");
}
return channelAuthHelper.buildAuthorisationModel(channel);
}
}

View File

@@ -20,11 +20,9 @@
package org.alfresco.repo.web.scripts.publishing; package org.alfresco.repo.web.scripts.publishing;
import java.util.Map; import java.util.Map;
import java.util.TreeMap;
import org.alfresco.service.cmr.publishing.channels.Channel; import org.alfresco.service.cmr.publishing.channels.Channel;
import org.alfresco.service.cmr.publishing.channels.ChannelService; 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.Cache;
import org.springframework.extensions.webscripts.DeclarativeWebScript; import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.Status;
@@ -53,24 +51,6 @@ public class ChannelsPostWebScript extends DeclarativeWebScript
Channel newChannel = channelService.createChannel(channelType, channelName, null); Channel newChannel = channelService.createChannel(channelType, channelName, null);
NodeRef channelNodeRef = newChannel.getNodeRef(); return channelAuthHelper.buildAuthorisationModel(newChannel);
String callbackUrl = channelAuthHelper.getAuthoriseCallbackUrl(channelNodeRef);
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 = channelAuthHelper.getDefaultAuthoriseUrl(channelNodeRef);
}
Map<String, Object> model = new TreeMap<String, Object>();
model.put("authoriseUrl", authoriseUrl);
model.put("channelId", newChannel.getId());
model.put("authCallbackUrl", callbackUrl);
return model;
} }
} }