diff --git a/config/alfresco/application-context-highlevel.xml b/config/alfresco/application-context-highlevel.xml index 25521ddc42..1bfd709f25 100644 --- a/config/alfresco/application-context-highlevel.xml +++ b/config/alfresco/application-context-highlevel.xml @@ -28,5 +28,6 @@ + diff --git a/config/alfresco/facebook-publishing-context.xml b/config/alfresco/facebook-publishing-context.xml new file mode 100644 index 0000000000..3e45992057 --- /dev/null +++ b/config/alfresco/facebook-publishing-context.xml @@ -0,0 +1,27 @@ + + + + + + + + alfresco/model/facebookPublishingModel.xml + + + + + + + + + + + + + + + + + + + diff --git a/config/alfresco/model/facebookPublishingModel.xml b/config/alfresco/model/facebookPublishingModel.xml index 3c83e65adf..fbf3755bb4 100644 --- a/config/alfresco/model/facebookPublishingModel.xml +++ b/config/alfresco/model/facebookPublishingModel.xml @@ -32,22 +32,7 @@ Facebook Delivery Channel Aspect Applied to a node that represents a Facebook delivery channel - pub:UserPasswordDeliveryChannelAspect - - - - Facebook Asset - Applied to a node that has been published to Facebook - - - Facebook Asset Id - d:text - - - Facebook Asset URL - d:text - - + pub:OAuth2DeliveryChannelAspect diff --git a/config/alfresco/model/publishingModel.xml b/config/alfresco/model/publishingModel.xml index 28e9e83aed..79acd8a734 100644 --- a/config/alfresco/model/publishingModel.xml +++ b/config/alfresco/model/publishingModel.xml @@ -321,6 +321,18 @@ + + OAuth2 Authenticated Delivery Channel + Applied to delivery channels that use OAuth2 + + + The value of the OAuth2 token + d:text + false + + + + Username and Password Authenticated Delivery Channel Applied to delivery channels that use OAuth1 @@ -338,5 +350,19 @@ + + Published Asset + Applied to a node that has been published to an external delivery service + + + Published Asset Id + d:text + + + Published Asset URL + d:text + + + diff --git a/source/java/org/alfresco/repo/publishing/PublishingEventProcessor.java b/source/java/org/alfresco/repo/publishing/PublishingEventProcessor.java index fd62e073f8..bc1586cd78 100644 --- a/source/java/org/alfresco/repo/publishing/PublishingEventProcessor.java +++ b/source/java/org/alfresco/repo/publishing/PublishingEventProcessor.java @@ -83,7 +83,7 @@ public class PublishingEventProcessor { publishEvent(channel, event); updateStatus(channel, environment, event.getStatusUpdate()); - String completedStatus = PublishingEvent.Status.COMPLETE.name(); + String completedStatus = PublishingEvent.Status.COMPLETED.name(); nodeService.setProperty(eventNode, PublishingModel.PROP_PUBLISHING_EVENT_STATUS, completedStatus); } } diff --git a/source/java/org/alfresco/repo/publishing/PublishingModel.java b/source/java/org/alfresco/repo/publishing/PublishingModel.java index e263ec8900..0210847b0a 100644 --- a/source/java/org/alfresco/repo/publishing/PublishingModel.java +++ b/source/java/org/alfresco/repo/publishing/PublishingModel.java @@ -45,6 +45,8 @@ public interface PublishingModel public static final QName ASPECT_CHANNEL_INFO= QName.createQName(NAMESPACE, "channelInfo"); public static final QName ASPECT_PUBLISHED = QName.createQName(NAMESPACE, "published"); public static final QName ASPECT_OAUTH1_DELIVERY_CHANNEL = QName.createQName(NAMESPACE, "OAuth1DeliveryChannelAspect"); + public static final QName ASPECT_OAUTH2_DELIVERY_CHANNEL = QName.createQName(NAMESPACE, "OAuth2DeliveryChannelAspect"); + public static final QName ASPECT_ASSET = QName.createQName(NAMESPACE, "AssetAspect"); public static final QName PROP_CHANNEL = QName.createQName(NAMESPACE, "channel"); public static final QName PROP_CHANNEL_TYPE = QName.createQName(NAMESPACE, "channelType"); @@ -66,6 +68,9 @@ public interface PublishingModel public static final QName PROP_OAUTH1_TOKEN_SECRET = QName.createQName(NAMESPACE, "oauth1TokenSecret"); public static final QName PROP_CHANNEL_USERNAME = QName.createQName(NAMESPACE, "channelUsername"); public static final QName PROP_CHANNEL_PASSWORD = QName.createQName(NAMESPACE, "channelPassword"); + public static final QName PROP_OAUTH2_TOKEN = QName.createQName(NAMESPACE, "oauth2Token"); + public static final QName PROP_ASSET_ID = QName.createQName(NAMESPACE, "assetId"); + public static final QName PROP_ASSET_URL = QName.createQName(NAMESPACE, "assetUrl"); // Publishing Connection Properties diff --git a/source/java/org/alfresco/repo/publishing/facebook/FacebookChannelType.java b/source/java/org/alfresco/repo/publishing/facebook/FacebookChannelType.java index 74d5478069..a4a1f2bbd6 100644 --- a/source/java/org/alfresco/repo/publishing/facebook/FacebookChannelType.java +++ b/source/java/org/alfresco/repo/publishing/facebook/FacebookChannelType.java @@ -20,6 +20,7 @@ package org.alfresco.repo.publishing.facebook; import java.io.Serializable; import java.util.Collections; +import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -27,36 +28,33 @@ import org.alfresco.repo.publishing.AbstractChannelType; import org.alfresco.repo.publishing.PublishingModel; import org.alfresco.service.cmr.publishing.channels.Channel; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.namespace.QName; import org.alfresco.util.ParameterCheck; import org.springframework.social.connect.Connection; import org.springframework.social.facebook.api.Facebook; -import org.springframework.social.oauth1.AuthorizedRequestToken; -import org.springframework.social.oauth1.OAuth1Operations; -import org.springframework.social.oauth1.OAuth1Parameters; -import org.springframework.social.oauth1.OAuthToken; +import org.springframework.social.oauth2.AccessGrant; import org.springframework.social.oauth2.GrantType; import org.springframework.social.oauth2.OAuth2Operations; import org.springframework.social.oauth2.OAuth2Parameters; -import org.springframework.social.twitter.api.Twitter; public class FacebookChannelType extends AbstractChannelType { public final static String ID = "facebook"; - private NodeService nodeService; + public final static String DEFAULT_REDIRECT_URI = "http://cognite.net"; + private FacebookPublishingHelper publishingHelper; - - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; - } + private String redirectUri = DEFAULT_REDIRECT_URI; public void setPublishingHelper(FacebookPublishingHelper facebookPublishingHelper) { this.publishingHelper = facebookPublishingHelper; } + public void setRedirectUri(String redirectUri) + { + this.redirectUri = redirectUri; + } + @Override public boolean canPublish() { @@ -119,14 +117,9 @@ public class FacebookChannelType extends AbstractChannelType @Override public String getNodeUrl(NodeRef node) { - String url = null; - if (node != null && nodeService.exists(node) && nodeService.hasAspect(node, FacebookPublishingModel.ASPECT_ASSET)) - { - url = (String)nodeService.getProperty(node, FacebookPublishingModel.PROP_ASSET_URL); - } - return url; + return null; } - + @Override public String getAuthorisationUrl(Channel channel, String callbackUrl) { @@ -136,33 +129,42 @@ public class FacebookChannelType extends AbstractChannelType { throw new IllegalArgumentException("Invalid channel type: " + channel.getChannelType().getId()); } - + + NodeRef channelRef = channel.getNodeRef(); + StringBuilder authStateBuilder = new StringBuilder(channelRef.getStoreRef().getProtocol()).append('.').append( + channelRef.getStoreRef().getIdentifier()).append('.').append(channelRef.getId()); OAuth2Operations oauthOperations = publishingHelper.getConnectionFactory().getOAuthOperations(); - return oauthOperations.buildAuthorizeUrl(GrantType.AUTHORIZATION_CODE, new OAuth2Parameters(callbackUrl)); + OAuth2Parameters params = new OAuth2Parameters(redirectUri, + "publish_stream,offline_access,user_photos,user_videos", authStateBuilder.toString(), null); + return oauthOperations.buildAuthorizeUrl(GrantType.IMPLICIT_GRANT, params); } - + @Override public boolean acceptAuthorisationCallback(Channel channel, Map callbackHeaders, Map callbackParams) { boolean authorised = false; - //FIXME: BJR: 20110708: Write this. -// String[] verifier = callbackParams.get("oauth_verifier"); -// if (verifier != null) -// { -// OAuth2Operations oauthOperations = publishingHelper.getConnectionFactory().getOAuthOperations(); -// NodeRef channelNodeRef = channel.getNodeRef(); -// -// Map props = nodeService.getProperties(channelNodeRef); -// String tokenValue = (String) props.get(PublishingModel.PROP_OAUTH1_TOKEN_VALUE); -// String tokenSecret = (String) props.get(PublishingModel.PROP_OAUTH1_TOKEN_SECRET); -// OAuthToken token = new OAuthToken(tokenValue, tokenSecret); -// OAuthToken accessToken = oauthOperations.exchangeForAccessToken(new AuthorizedRequestToken(token, verifier[0]), null); -// nodeService.setProperty(channelNodeRef, PublishingModel.PROP_OAUTH1_TOKEN_VALUE, accessToken.getValue()); -// nodeService.setProperty(channelNodeRef, PublishingModel.PROP_OAUTH1_TOKEN_SECRET, accessToken.getSecret()); -// -// authorised = true; -// } + + String accessToken = null; + if (callbackParams.containsKey("access_token")) + { + //We have been given the access token directly. + accessToken = callbackParams.get("access_token")[0]; + } + else if (callbackParams.containsKey("code")) + { + //We have been passed an authorisation code that needs to be exchanged for a token + OAuth2Operations oauthOps = publishingHelper.getConnectionFactory().getOAuthOperations(); + AccessGrant grant = oauthOps.exchangeForAccess(callbackParams.get("code")[0], redirectUri, null); + accessToken = grant.getAccessToken(); + } + if (accessToken != null) + { + Map channelProps = new HashMap(); + channelProps.put(PublishingModel.PROP_OAUTH2_TOKEN, accessToken); + getChannelService().updateChannel(channel, channelProps); + authorised = true; + } return authorised; } } diff --git a/source/java/org/alfresco/repo/publishing/facebook/FacebookPublishingHelper.java b/source/java/org/alfresco/repo/publishing/facebook/FacebookPublishingHelper.java index 03f07a4cad..de798dff4e 100644 --- a/source/java/org/alfresco/repo/publishing/facebook/FacebookPublishingHelper.java +++ b/source/java/org/alfresco/repo/publishing/facebook/FacebookPublishingHelper.java @@ -52,13 +52,12 @@ public class FacebookPublishingHelper if (nodeService.exists(channelNode) && nodeService.hasAspect(channelNode, FacebookPublishingModel.ASPECT_DELIVERY_CHANNEL)) { - String tokenValue = (String) nodeService.getProperty(channelNode, PublishingModel.PROP_OAUTH1_TOKEN_VALUE); - String tokenSecret = (String) nodeService.getProperty(channelNode, PublishingModel.PROP_OAUTH1_TOKEN_SECRET); + String tokenValue = (String) nodeService.getProperty(channelNode, PublishingModel.PROP_OAUTH2_TOKEN); Boolean danceComplete = (Boolean) nodeService.getProperty(channelNode, PublishingModel.PROP_AUTHORISATION_COMPLETE); if (danceComplete) { - AccessGrant token = new AccessGrant(" "); + AccessGrant token = new AccessGrant(tokenValue); connection = connectionFactory.createConnection(token); } } diff --git a/source/java/org/alfresco/repo/publishing/facebook/FacebookPublishingModel.java b/source/java/org/alfresco/repo/publishing/facebook/FacebookPublishingModel.java index 9583213930..b355b6d542 100644 --- a/source/java/org/alfresco/repo/publishing/facebook/FacebookPublishingModel.java +++ b/source/java/org/alfresco/repo/publishing/facebook/FacebookPublishingModel.java @@ -33,8 +33,4 @@ public interface FacebookPublishingModel public static final QName TYPE_DELIVERY_CHANNEL = QName.createQName(NAMESPACE, "DeliveryChannel"); public static final QName ASPECT_DELIVERY_CHANNEL = QName.createQName(NAMESPACE, "DeliveryChannelAspect"); - - public static final QName ASPECT_ASSET = QName.createQName(NAMESPACE, "AssetAspect"); - public static final QName PROP_ASSET_ID = QName.createQName(NAMESPACE, "assetId"); - public static final QName PROP_ASSET_URL = QName.createQName(NAMESPACE, "assetUrl"); } diff --git a/source/java/org/alfresco/service/cmr/publishing/PublishingEvent.java b/source/java/org/alfresco/service/cmr/publishing/PublishingEvent.java index 751a3bf253..9e740527c2 100644 --- a/source/java/org/alfresco/service/cmr/publishing/PublishingEvent.java +++ b/source/java/org/alfresco/service/cmr/publishing/PublishingEvent.java @@ -29,7 +29,7 @@ import java.util.Date; */ public interface PublishingEvent { - enum Status {SCHEDULED, IN_PROGRESS, CANCEL_REQUESTED, COMPLETE, FAILED} + enum Status {SCHEDULED, IN_PROGRESS, CANCEL_REQUESTED, COMPLETED, FAILED} String getId();