Difference between revisions of "On-click add-on installation"

Jump to: navigation, search
m (Communication protocol: Hopefully the last clarification of the site info spec)
(Communication protocol: fixed site name sanitization, we really do not expect HTML there)
Line 99: Line 99:
<code php>
<code php>
$siteinfo = array(
$siteinfo = array(
     'fullname' => s($SITE->fullname),           // e.g. 'My School Online Courses'
     'fullname' => strip_tags($SITE->fullname), // e.g. 'My School Online Courses'
     'url' => $CFG->wwwroot,                    // e.g. 'http://my.school.edu/moodle'
     'url' => $CFG->wwwroot,                    // e.g. 'http://my.school.edu/moodle'
     'majorversion' => moodle_major_version(),  // e.g. '2.5'
     'majorversion' => moodle_major_version(),  // e.g. '2.5'

Revision as of 17:13, 22 March 2013

On-click add-on installation
Project state In progress
Tracker issue MDLSITE-2107
Discussion N/A
Assignee David Mudrak, Aparup Banerjee

Moodle 2.5

This is a follow-up project on Automatic updates deployment aiming to implement the Episode III of the deployment saga.

Use cases

Sue the admin
Meet Sue, a Moodle administrator. She runs her Moodle at a cheap web hosting company where she gets an FTP access only (and some basic web tool to administer one SQL database). No shell access, no way to use Git etc. She never modifies source codes manually. And she likes the way how new apps can be installed into her Android smart phone by browsing the Google Play site.

Use case 1

  • Sue logs in her Moodle site and goes to the Plugins overview page. She clicks the "Get more add-ons!" link at the top of the page.
  • She is redirected to the Plugins directory. The Moodle version there is automatically set to the version of her Moodle site she just came from.
  • She browses the list of plugins in the directory and finally finds an add-on she want to install.
  • There is a big nice icon "Install" at the page so she clicks it.
  • A popup-like overlay window is displayed with the list of Sue's sites. She has one site only so she clicks the "Install to this site" link next to it.
  • She is redirected back to her site, to a page requiring her confirmation for the plugin installation. She confirms that she really wants to install that add-on by click at "Install" button.
  • The Plugins check page appears, showing that there is the plugin ready to be installed (as if she just unzipped to her site).


There are two basic scenarios: The user (admin) starts at their site and clicks the "Get more add-ons!" link, or the user visits moodle.org/plugins directly. In both scenarios, the user may or may not have an account at moodle.org and may or may not be logged in there. In the second scenario the user may and may not be logged in at their site. Their site may or may not be Moodle 2.5 (and higher).


(1) Admin logs in their Moodle site and navigates to the "Plugins overview" page.

(2) Admin clicks the "Get more add-ons!" link at the top of the page.

(3) The link leads to a script like https://moodle.org/plugins/get.php?site=... where the parameter holds the encoded information about the site name, URL and branch.

(4) Plugins directory decodes the site information. Then ...

(4.1) If the user is not logged-in at moodle.org, they are asked if they want to log in (with a help icon to explain why login is useful).

(4.1.1) If they decide to continue in anonymous mode, the site information is stored in the MUC session cache, the Moodle version is set to the branch provided by the link (3) and they are redirected to the main moodle.org/plugins page.

(4.1.2) If they decide to log in, they are redirected to the login form, having the link (3) set in their $SESSION->wantsurl - thence jumping to (4.2).

(4.2) If the user is logged-in at moodle.org, the passed site information is compared with the list of their "own" sites recorded in their user preferences. If there is a change in the name name or the branch, or such URL is not recorded yet, they are asked to update it/add it to the list of their Moodle sites.

(5) The user navigates to the plugin they want to install. The "Install" button is displayed at the page.

(5.1) If they are logged-in, clicking the button opens a popup-like overlay window with the list of all recorded user's sites with a possibility to add a new site or delete an existing site. The "Install to this site" link is displayed next to each recorded site if its branch >= 2.5.

(5.2) If they are not logged in, clicking the button opens a popup-like overlay window with an input field for the site URL and the submit button labelled "Install to this site". If the MUC session cache contains the information about the site they came from, that site's URL is pre-filled in the field.

(6) Clicking the "Install to this site" button takes them to that site's /index.php. Additional information about the plugin version to be installed is passed via encoded HTTP GET parameter 'installaddon'.

(7) If optional_param('installaddon') is passed to /index.php, the user must log in as the admin (if they are not yet). A screen requiring their confirmation to install the given add-on is displayed. The sesskey is checked during the confirmation. For sites running 2.4.x and lower, nothing will happen.

(8) The site uses cURL call via HTTPS to fetch meta-information about the plugin to be installed, most notably the URL and the MD5 hash of the ZIP package to be downloaded. This information is to be provided by https://download.moodle.org/api/1.2/describe.php?plugin=frankenstyle_name&version=the_plugin_version (which in turn pulls data from local_plugins WS every now and then and when needed).

(9) The information about the given plugin and it's version is loaded from the database and the JSON response is prepared.

(10) The JSON response is sent back to the site.

(11) The parameters for the mdeploy.php script are prepared.

(12) The mdeploy.php utility is executed.

(13) The cURL GET call to download the ZIP.

(14) ZIP package is downloaded.

(15) ZIP is extracted into the correct location.

(16) The browser is redirected into the /admin to perform the installation.

Implementation plan

The existing standalone utility mdeploy.php will be responsible for actual fetching and deploying the ZIP packages from moodle.org/plugins.

Required functionality for Moodle sites

  • mdeploy.php supports the add-on installation mode
  • UI to jump to moodle.org/plugins
  • UI to confirm installation
  • fetching the plugin meta-info

Required functionality for the Plugins directory

  • Owned sites management - how to store them?
  • MUC session cache for anonymous landings
  • API providing the meta-information about the plugin
  • UI to handle "Install" button clicks

Communication protocol

For the step (3), when the admin clicks "Install add-ons from Moodle plugins directory" at their site, they will be redirected to https://moodle.org/plugins/get.php?site=xxx where the value of the xxx parameter is encoded using a code like this:

$siteinfo = array(
    'fullname' => strip_tags($SITE->fullname),  // e.g. 'My School Online Courses'
    'url' => $CFG->wwwroot,                     // e.g. 'http://my.school.edu/moodle'
    'majorversion' => moodle_major_version(),   // e.g. '2.5'
$jsonized = json_encode($siteinfo);
$encoded = base64_encode($jsonized);
$goto = new moodle_url('https://moodle.org/plugins/get.php', array('site' => $encoded));

For the step (6), when the admin clicks "Install" at a plugin page at moodle.org/plugins, they will be redirected to http://url.of.their.site/admin/index.php?installaddonrequest=plugintype_pluginname@explicitversion where the @explicitversion part is optional. If the version is present, then the admin wants to install specific version of the plugin, e.g. ?installaddonrequest=mod_stampcoll@2012062201. If the version is not present (which may happen for themes, for example), then the most recent available version for their major Moodle version is to be installed.

If the parameter installaddonrequest is detected at admin/index.php, its value is dispatched to the new admin tool_installaddon. It then fetches additional data about the requested plugin (such as ZIP URL, ZIP hash etc) from https://download.moodle.org/api/1.2/install.php and lets the admin to confirm their intention. Once confirmed, the ZIP is downloaded, its content hash is compared and if successful, the installation happens as if the admin uploaded the ZIP via the upload form (which is part of the tool_installaddon, too).