First, for those of you who prefer reading code rather than blogs: https://github.com/ldoguin/nuxeo-yammer-sample.

Now let's talk about OAuth. OAuth is a very common way to authenticate with social networks, websites or applications. I am going to show you how you can do it in Nuxeo.

OAuth


We already use OAuth for our OpenSocial gadgets since it comes as a Shindig dependency, which lets us share Nuxeo gadgets in external containers. It's time to extend that. We need to let users grant access to any service provider registered in the Nuxeo Admin Center. We've added some code to handle the three-legged authentication. This will help through the different phases (request, authorization, access). Then I wrote a quick WebEngine module to use it in Nuxeo. This is really straightforward using the IDE. You select WebEngine project in the wizard and you get a simple WebEngine site that you can extend and modify quickly using the hot reload features of the IDE. This module can handle three different URLs:

1. http://mysite/nuxeo/site/oauthsubscriber?servicename=myServiceProviderName&serviceurl=myURLencodedServiceProviderURL

This page will show the service provider name and description, ask you if you want to authorize it, and will let you enter a code given by the service provider, if necessary. You need to give the service provider name and URL as query parameters.

2. http://mysite/nuxeo/site/oauthsubscriber/authorize?servicename=myServiceProviderName&serviceurl=myURLencodedServiceProviderURL
Authorize Nuxeo to access Yammer
This will start the authorization process. Two things can happen. In the best case, your service provider supports callback. Once you click on the link, a new page will open and ask you if you want to authorize Nuxeo. Once you click, you are redirected to a page saying you are registered. In the worst case, your service provider does not handle callback. You get a code that you have to enter manually on the WebEngine OAuth subscriber page. Once you've entered the code, you should land on the page saying you are registered.

3. http://mysite/nuxeo/site/oauthsubscriber/callback?servicename=myServiceProviderName&serviceurl=myURLencodedServiceProviderURL
Given code when callback is not supported
This is the URL where you are redirected if the service provider supports callback.

Now I have everything I need to ask authorization to a service provider. I can store the secret token and use it to sign every request the user will make to the service provider.

Speaking of service providers, you'll need to register the service provider in the Admin Center. You need to give the name and the URL of the service. Be careful, they are used to identifying your service. You also need to fill in the following fields: description, request, authorization and access URLs, the consumer key and the consumer secret key.

Register your service provider in the admin center

Real Life Example: Yammer


This is actually the reason I started playing with OAuth. Yammer can be really useful when your team is split between Paris, New York and Boston. And I know Roland and Eric were getting frustrated when they could not share documents from our Intranet to Yammer. I'm happy to say that this is not an issue anymore :D
It's actually pretty easy to set up once you've taken care of the OAuth part. All you need is a simple operation and Nuxeo Studio. The goal is to code an operation that posts the message on Yammer using a document and uses it in an operation chain in Studio.

Share a document in Yammer

So about that operation, the quickest way to do this is again to use Nuxeo IDE. Create a new project and a new operation. Here's what the code looks like:

@Operation(id = ShareInYammer.ID, category = Constants.CAT_DOCUMENT, label = "ShareInYammer", description = "This operation will post the given document and comment on yammer")
public class ShareInYammer {

public static final String ID = "ShareInYammer";

@Context
public CoreSession coreSession;

@Param(name = "document")
public DocumentModel doc;

@Param(name = "comment")
public String comment;

@OperationMethod
public void run() throws Exception {
OAuthAccessor accessor = NuxeoOAuthClient.buildSigningAccessor(
WEOAuthConstants.getDefaultCallbackURL(),
YammerConstants.GADGET_URL,
YammerConstants.YAMMER_SERVICE_PROVIDER_NAME,
coreSession.getPrincipal().getName());
OAuthClient client = new OAuthClient(new URLConnectionClient());
final List<OAuth.Parameter> parameters = OAuth.newList(
YammerConstants.YAMMER_MESSAGE_BODY_PROPERTY_NAME, comment,
YammerConstants.YAMMER_OPEN_GRAPH_TITLE_PROPERTY_NAME, doc.getTitle(),
YammerConstants.YAMMER_OPEN_GRAPH_DESCRIPTION_PROPERTY_NAME,
doc.getProperty("dc:description").getValue(String.class),
YammerConstants.YAMMER_OPEN_GRAPH_TYPE_PROPERTY_NAME,
YammerConstants.YAMMER_OPEN_GRAPH_TYPE_DOCUMENT_PROPERTY_NAME,
YammerConstants.YAMMER_OPEN_GRAPH_URL_PROPERTY_NAME,
DocumentModelFunctions.documentUrl(doc));

client.invoke(accessor, OAuthMessage.POST,
YammerConstants.YAMMER_MESSAGE_POST_URL, parameters);
}

}

Now it's easy to export your operation to your Studio account and use it in your project.

All the source code is available on GitHub: https://github.com/ldoguin/nuxeo-yammer-sample.

That's it for today. See you next Monday :)