OAuth

OAuth is a security protocol designed to allow delegated API Access. It is available on the Elgg platform through the OAuth Plugin. This page is meant to document usage of the OAuth plugin from within Elgg, not to explain the use of the OAuth protocol itself.

Contents

Library

The OAuth Plugin is a library that allows an Elgg installation to act as a client or a server in an OAuth-protected mechanism. User-facing access to the plugin is available through the "Applications" link on the tools menu.

The OAuth Plugin supports both version 1.0 and revision 1.0a of the OAuth protocol. Consumers must be flagged as supporting 1.0a at creation time, either by checking the "1.0a" checkbox upon registration or by passing a flag to the oauth_create_consumer function call.

Outbound

The outbound (client) functionality allows an Elgg site to connect outward to another OAuth-protected site or resource. The OAuth plugin will manage all necessary tokens and consumers as Entity objects in the database. The plugin also provides views and actions for requesting tokens from a far side site.

Note that the code mentioned here is meant to go into your own plugin's space and not in the OAuth plugin itself!

Creating a Consumer

When you register your consumer with the site you want to access, you will be given a consumer key and consumer secret. These must be stored into an Elgg consumer with the OAuth plugin in order for it to be accessible by the plugin. To do so, make the call in your client plugin:

$consumEnt = oauth_create_consumer('Name', 'Short Description Text', 'key', 'secret');

Saving a Consumer in a Plugin

You also need to keep a reference to this consumer someplace. I generally save the GUID on the plugin settings:

set_plugin_setting('oauthConsumer', $consumEnt->getGUID());

In order to make these settings admin-editable, I've found it useful to expose a couple text fields in the plugin settings view, and then capture their updates to be saved to the consumer entity through the use of the 'plugin:setting' hook. Below is an example of this method.

First, we register our callback inside of my_plugin_init():

register_plugin_hook('plugin:setting', 'all', 'my_plugin_plugin_setting');

Then we listen for the plugin settings to be saved and save our consumer key and secret information from the plugins panel:

function my_plugin_plugin_setting($hook, $entity_type, $returnvalue, $params) {
	global $CONFIG;

	$plugin = $params['plugin'];
	$name = $params['name'];
	$value = $params['value'];

	if ($plugin == 'my_plugin' && ($name == 'oauthKey' || $name == 'oauthSecret')) {
		// have to check for name here --^ , otherwise we get
		// into a bad loop ... 

		$consumEnt = my_plugin_oauth_consumer_entity();

		if ($name == 'oauthKey' && $value) {
			$consumEnt->key = $value;
		} else if ($name == 'oauthSecret' && $value) {
			$consumEnt->secret = $value;
		}
	}
	return $returnvalue;
}

Finally, we use a utility function to store and create the consumer:

function my_plugin_oauth_consumer_entity() {
	$consGuid = get_plugin_setting('oauthConsumer', 'my_plugin');

	$consumEnt = NULL;

	if ($consGuid) {
		$consumEnt = get_entity($consGuid);
	}

	if ($consumEnt == NULL) {
		// don't have a consumer entity yet
		$consumEnt = oauth_create_consumer('My Plugin', 'My Plugin OAuth consumer', NULL, NULL, TRUE); // no key-secret yet, is revision a
		set_plugin_setting('oauthConsumer', $consumEnt->getGUID(), 'my_plugin');
	}

	return $consumEnt;
}

Checking for a Token

To see if a user already has a token available, you can use a lookup function that takes in a Consumer object and a User object.

$token = oauth_get_token($user, $consumer);

If $token is not NULL, then it is a valid OAuth token tied to that user and consumer pairing. If $token->requestToken is not NULL, the token is a request token. Likewise if $token->accessToken is not NULL, the token is an access token.

Getting a Request Token

Use the oauth/tokenform view to start the OAuth authentication process. This will automatically step the user through the actions of getting a request token, validating that token, and trading it for an access token. It takes the following arguments:

  • msg: a text message to display to the user. If this is left out, the system will use a generic one.
  • consumer_key: the key for the consumer, used to look up the consumer object downstream
  • user_auth: URL for user authentication for the service you're trying to access
  • request_url: URL for getting request tokens
  • access_url: URL for trading validated request tokens for access tokens
  • return_to: URL to return to once this whole process is complete

This form uses the actions oauth/gettoken and oauth/gottoken to do its work.

Revoking Tokens

One of the benefits of OAuth is that tokens no longer used, or tokens thought to have been compromised, can be revoked from either end of the transaction. Users can view and revoke their existing tokens by going to the Applications entry in the Tool menu.

Inbound

The inbound (server) functionality allows other software to access an Elgg instance using OAuth as the authentication mechanism. This works by allowing users to register consumer applications on the site and using those consumers to get request and access tokens. The validated access tokens can then be used as an authentication key (using the standard OAuth protocol) to access any URL on the site, though it makes the most sense for the Elgg API.

Registering a Consumer

To register your consumer on the Elgg site, you must be logged in as an administrator. On the Adminstrator page, select "Registered Consumer Applications" from the sidebar menu. From here you can register a new consumer which you can then use to access the Elgg site.

Note that if you leave the 'key' and 'secret' fields blank, random values will be generated for you. This is preferable to choosing your own.

Getting Tokens for Your Users

The OAuth protocol requires three defined endpoints. For a given Elgg instance, these are (relative to the site root URL):

  • Request a new request token:
    • /pg/oauth/requesttoken
  • Have a user validate a request token:
    • /pg/oauth/authorize
  • Trade a request token for an access token:
    • /pg/oauth/accesstoken

Using your Consumer

You use the consumer just as you would any other OAuth consumer. The plugin works by hooking into the PAM system within Elgg and validating OAuth credentials, if they exist on the query.

Example on usage

You can find detailed example of how the oauth system on elgg is used at: Testing OAuth on N-1

Search docs