In this article, Ian Wild, the author of the book, Moodle 3.x Developer's Guide will be intoroducing you to Moodle 3.For any organization considering implementing an online learning environment, Moodle is often the number one choice. Key to its success is the free, open source ethos that underpins it. Not only is the Moodle source code fully available to developers, but Moodle itself has been developed to allow for the inclusion of third party plugins. Everything from how users access the platform, the kinds of teaching interactions that are available, through to how attendance and success can be reported – in fact all the key Moodle functionality – can be adapted and enhanced through plugins.
(For more resources related to this topic, see here.)
There are three reasons why Moodle has become so important, and much talked about, in the world of online learning, one technical, one philosophical and the third educational.
From a technical standpoint Moodle - an acronym for Modular Object Oriented Dynamic Learning Environment – is highly customizable. As a Moodle developer, always remember that the ‘M’ in Moodle stands for modular. If you are faced with a client feature request that demands a feature Moodle doesn’t support then don’t panic. The answer is simple: we create a new custom plugin to implement it. Check out the Moodle Plugins Directory (https://moodle.org/plugins/) for a comprehensive library of supported 3rd party plugins that Moodle developers have created and given back to the community. And this leads to the philosophical reason why Moodle dominates.
Moodle is grounded firmly in a community-based, open source philosophy (see https://en.wikipedia.org/wiki/Open-source_model). But what does this mean for developers? Fundamentally, it means that we have complete access to the source code and, within reason, unfettered access to the people who develop it. Access to the application itself is free – you don’t need to pay to download it and you don’t need to pay to run it. But be aware of what ‘free’ means in this context. Hosting and administration, for example, take time and resources and are very unlikely to be free.
As an educational tool, Moodle was developed to support social constructionism (see https://docs.moodle.org/31/en/Pedagogy) – if you are not familiar with this concept then it is essentially suggesting that building an understanding of a concept or idea can be best achieved by interacting with a broad community. The impact on us as Moodle plugin developers is that there is a highly active group of users and developers. Before you begin developing any Moodle plugins come and join us at https://moodle.org.
In this article, we will be developing a novel plugin that will seamlessly integrate Moodle and the WordPress content management system. Our plugin will authorize users via WordPress when they click on a link to Moodle when on a WordPress page. The plugin discussed in this article has already been released to the Moodle community – check out the Moodle Plugins Directory at https://moodle.org/plugins/auth_wordpress for details.
Let us start by learning what Moodle authentication is and how new user accounts are created.
Moodle supports a range of different authentication methods out of the box, each one supported by its own plugin. To go to the list of available plugins, from the Administration block, click on Site administration, click Plugins, then click Authentication, and finally click on Manage authentication. The list of currently installed authentication plugins is displayed:
Each plugin interfaces with an internal Application Programming Interface (API), the Access API – see the Moodle developer documentation for details here: https://docs.moodle.org/dev/Access_API
There are two ways of prompting the Moodle authentication process:
For an overview of the process, take a look in the developer documentation at https://docs.moodle.org/dev/Authentication_plugins#Overview_of_Moodle_authentication_process. After checks to determine if an upgrade is required (or if we are partway through the upgrade process), there is a short fragment of code that loads the configured authentication plugins and for each one calls a special method called loginpage_hook():
$authsequence = get_enabled_auth_plugins(true); // auths, in sequence
foreach($authsequence as $authname) {
$authplugin = get_auth_plugin($authname);
$authplugin->loginpage_hook();
}
The loginpage_hook() function gives each authentication plugin the chance to intercept the login. Assuming that the login has not been intercepted, the process then continues with a check to ensure the supplied username conforms to the configured standard before calling authenticate_user_login() which, if successful, returns a $user object.
The OAuth authentication mechanism provides secure delegated access. OAuth supports a number of scenarios, including:
In this article we will be implementing such a mechanism means, in practice, that:
Having given an overview, here is the process again described in a little more detail:
The process ends with the client possessing permanent authorization tokens that can be used to access WP-API functions.
Obviously, the most effective way of learning about this process is to implement it so let’s go ahead and do that now.
The first step will be to add the OAuth 1.0a server plugin to WordPress. Why not the more recent OAuth 2.0 server plugin? This is because 2.0 only supports https:// and not http://. Also, internally (at least at time of writing) WordPress will only authenticate internally using either OAuth 1.0a or cookies.
Log into WordPress as an administrator and, from the Dashboard, hover the mouse over the Plugins menu item and click on Installed Plugins. The Plugins page is displayed. At the top of the page, press the Add New button:
As described previously, ensure that you install version 1.0a and not 2.0:
Once installed, we need to configure a new client. From the Dashboard menu, hover the mouse over Users and you will see a new Applications menu item has been added. Click on this to display the Registered Applications page. Click the Add New button to display the Add Application page:
The Consumer Name is the title for our client that will appear in the Applications page, and Description is a brief explanation of that client to aid with the identification. The Callback is the URI that WordPress will talk to (refer to the outline of the OAuth authentication steps). As we have not yet developed the Moodle/OAuth client end yet you can specify oob in Callback (this stands for ‘out of band’). Once configured, WordPress will generate new OAuth credentials, a Client Key and a Client Secret:
Having installed and configured the server end now it’s time to develop the client.
Before we begin, download the finished plugin from https://github.com/iandavidwild/moodle-auth_wordpress and install it in your local development Moodle instance.
The development of a new authentication plugin is described in the developer documentation at https://docs.moodle.org/dev/Authentication_plugins. As described there, let us start with copying the none plugin (the no login authentication method) and using this as a template for our new plugin. In Eclipse, I’m going to copy the none plugin to a new authentication method called wordpress:
That done, we need to update the occurrences of auth_none to auth_wordpress. Firstly, rename /auth/wordpress/lang/en/auth_none.php to auth_wordpress.php. Then, in auth.php we need to rename the class auth_plugin_none to auth_plugin_wordpress. As described, the Eclipse Find/Replace function is great for updating scripts:
Next, we need to update version information in version.php. Update all the relevant names, descriptions and dates.
Finally, we can check that Moodle recognises our new plugin by navigating to the Site administration menu and clicking on Notifications. If installation is successful, our new plugin will be listed on the Available authentication plugins page:
Let us start with considering the plugin configuration. We will need to allow a Moodle administrator to configure the following:
There is very little flexibility in the design of an authentication plugin configuration page so at this stage, rather than creating a wireframe drawing and having this agreed with the client, we can simply go ahead and write the code. The configuration page is defined in /config.html. Remember to start declaring the relevant language strings in /lang/en/auth_wordpress.php.
Configuration settings themselves will be managed by the Moodle framework by calling our plugin’s process_config() method. Here is the declaration:
/**
* Processes and stores configuration data for this authentication plugin.
*
* @return @bool
*/
function process_config($config) {
// Set to defaults if undefined
if (!isset($config->wordpress_host)) {
$config->wordpress_host = ‘‘;
}
if (!isset($config->client_key)) {
$config->client_key = ‘‘;
}
if (!isset($config->client_secret)) {
$config->client_secret = ‘‘;
}
set_config(‘wordpress_host’, trim($config->wordpress_host), ‘auth/wordpress’);
set_config(‘client_key’, trim($config->client_key), ‘auth/wordpress’);
set_config(‘client_secret’, trim($config->client_secret), ‘auth/wordpress’);
return true;
}
Having dealt with configuration, now let us start managing the actual OAuth process.
Rather than go into the details of how we can send HTTP requests to WordPress let’s use a third party library to do this work. The code I’m going to use is based on Abraham Williamstwitteroauth library (see https://github.com/abraham/twitteroauth). In Eclipse, take a look at the files OAuth.php and BasicOAuth.php for details. To use the library, you will need to add the following lines to the top of /wordpress/auth.php:
require_once($CFG->dirroot . ‘/auth/wordpress/OAuth.php’);
require_once($CFG->dirroot . ‘/auth/wordpress/BasicOAuth.php’);
use OAuth1BasicOauth;
Let’s now start work on handling the Moodle login event.
When a user clicks on link to a protected resource Moodle calls loginpage_hook() in each enabled authentication plugin. To handle this, let us first implement loginpage_hook(). We need to add the following lines to auth.php:
/**
* Will get called before the login page is shown.
*
*/
function loginpage_hook() {
$client_key = $this->config->client_key;
$client_secret = $this->config->client_secret;
$wordpress_host = $this->config->wordpress_host;
if( (strlen($wordpress_host) > 0) && (strlen($client_key) > 0) && (strlen($client_secret) > 0) ) {
// kick ff the authentication process
$connection = new BasicOAuth($client_key, $client_secret);
// strip the trailing slashes from the end of the host URL to avoid any confusion (and to make the code easier to read)
$wordpress_host = rtrim($wordpress_host, ‘/’);
$connection->host = $wordpress_host . “/wp-json”;
$connection->requestTokenURL = $wordpress_host . “/oauth1/request”;
$callback = $CFG->wwwroot . ‘/auth/wordpress/callback.php’;
$tempCredentials = $connection->getRequestToken($callback);
// Store temporary credentials in the $_SESSION
}// if
}
This implements the first leg of the authentication process and the variable $tempCredentials will now contain a temporary access token. We will need to store these temporary credentials and then call on the server to ask the user to authorize the connection (leg two). Add the following lines immediately after the // Store temporary credentials in the $_SESSION comment:
$_SESSION[‘oauth_token’] = $tempCredentials[‘oauth_token’];
$_SESSION[‘oauth_token_secret’] = $tempCredentials[‘oauth_token_secret’];
$connection->authorizeURL = $wordpress_host . “/oauth1/authorize”;
$redirect_url = $connection->getAuthorizeURL($tempCredentials);
header(‘Location: ‘ . $redirect_url);
die;
Next, we need to implement the OAuth callback. Create a new script called callback.php:
The callback.php script will need to:
The script is simple, short and available here: https://github.com/iandavidwild/moodle-auth_wordpress/blob/MOODLE_31_STABLE/callback.php
Now, in the auth.php script, we need to implement the callback_handler() method to auth_plugin_wordpress. You can check out the code in GitHub. Visit https://github.com/iandavidwild/moodle-auth_wordpress/blob/MOODLE_31_STABLE/auth.php and scroll down to the call_backhandler() method.
Lastly, let us add a fragment of code to the loginpage_hook() method that allows us to turn off WordPress authentication in config.php. Add the following to the very beginning of the loginpage_hook() function:
global $CFG;
if(isset($CFG->disablewordpressauth) && ($CFG->disablewordpressauth == true)) {
return;
}
In this article, we introduced the Moodle learning platform, investigated the open source philosophy that underpins it, and how Moodle’s functionality can be extended and enhanced through plugins. We took a pre-existing plugin to develop a new WordPress authentication module. This will allow a user logged into WordPress to automatically log into Moodle. To do so we implemented three legged Oauth 1.0a WordPress to Moodle authentication. Check out the complete code at https://github.com/iandavidwild/moodle-auth_wordpress/blob/MOODLE_31_STABLE/callback.php. More information on the plugin described in this article is available from the main Moodle website at https://moodle.org/plugins/auth_wordpress.
Further resources on this subject: