MDL-30740 repository: Add Microsoft Skydrive plugin
authorDan Poltawski <dan@moodle.com>
Sun, 13 May 2012 13:42:45 +0000 (21:42 +0800)
committerDan Poltawski <dan@moodle.com>
Mon, 15 Jul 2013 09:57:42 +0000 (17:57 +0800)
Thanks to Universidad Teconológica de Chile (INACAP) who funded this
work initially and LUNS who permitted this to be released open source so
I could continue to work on this.

repository/skydrive/db/access.php [new file with mode: 0644]
repository/skydrive/lang/en/repository_skydrive.php [new file with mode: 0644]
repository/skydrive/lib.php [new file with mode: 0644]
repository/skydrive/microsoftliveapi.php [new file with mode: 0644]
repository/skydrive/pix/icon.png [new file with mode: 0644]
repository/skydrive/version.php [new file with mode: 0644]

diff --git a/repository/skydrive/db/access.php b/repository/skydrive/db/access.php
new file mode 100644 (file)
index 0000000..6fe7ea2
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Capability definitions for skydrive repository
+ *
+ * @package    repository_skydrive
+ * @copyright  2012 Lancaster University Network Services Ltd
+ * @author     Dan Poltawski <dan.poltawski@luns.net.uk>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+$capabilities = array(
+    'repository/skydrive:view' => array(
+        'captype' => 'read',
+        'contextlevel' => CONTEXT_MODULE,
+        'archetypes' => array(
+            'user' => CAP_ALLOW
+        )
+    )
+);
diff --git a/repository/skydrive/lang/en/repository_skydrive.php b/repository/skydrive/lang/en/repository_skydrive.php
new file mode 100644 (file)
index 0000000..fe1c3fd
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Language file definitions for skydrive repository
+ *
+ * @package    repository_skydrive
+ * @copyright  2012 Lancaster University Network Services Ltd
+ * @author     Dan Poltawski <dan.poltawski@luns.net.uk>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+$string['clientid'] = 'Client ID';
+$string['configplugin'] = 'Configure Microsoft Skydrive';
+$string['oauthinfo'] = '<p>To use this plugin, you must register your site <a href="https://manage.dev.live.com/Applications/Index">with Microsoft</a>.<p>As part of the registration process, you will need to enter the following URL as \'Redirect domain\':</p><p>{$a->callbackurl}</p>Once registered, you will be provided with a client ID and secret which can be entered here.</p>';
+$string['pluginname'] = 'Microsoft Skydrive';
+$string['secret'] = 'Secret';
+$string['skydrive:view'] = 'View Skydrive';
diff --git a/repository/skydrive/lib.php b/repository/skydrive/lib.php
new file mode 100644 (file)
index 0000000..fe827a1
--- /dev/null
@@ -0,0 +1,183 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Microsoft Live Skydrive Repository Plugin
+ *
+ * @package    repository_skydrive
+ * @copyright  2012 Lancaster University Network Services Ltd
+ * @author     Dan Poltawski <dan.poltawski@luns.net.uk>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once('microsoftliveapi.php');
+
+/**
+ * Microsoft skydrive repository plugin.
+ *
+ * @package    repository_skydrive
+ * @copyright  2012 Lancaster University Network Services Ltd
+ * @author     Dan Poltawski <dan.poltawski@luns.net.uk>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class repository_skydrive extends repository {
+    /** @var microsoft_skydrive skydrive oauth2 api helper object */
+    private $skydrive = null;
+
+    /**
+     * Constructor
+     *
+     * @param int $repositoryid repository instance id.
+     * @param int|stdClass $context a context id or context object.
+     * @param array $options repository options.
+     */
+    public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) {
+        parent::__construct($repositoryid, $context, $options);
+
+        $clientid = get_config('skydrive', 'clientid');
+        $secret = get_config('skydrive', 'secret');
+        $returnurl = new moodle_url('/repository/repository_callback.php');
+        $returnurl->param('callback', 'yes');
+        $returnurl->param('repo_id', $this->id);
+        $returnurl->param('sesskey', sesskey());
+
+        $this->skydrive = new microsoft_skydrive($clientid, $secret, $returnurl);
+        $this->check_login();
+    }
+
+    /**
+     * Checks whether the user is logged in or not.
+     *
+     * @return bool true when logged in
+     */
+    public function check_login() {
+        return $this->skydrive->is_logged_in();
+    }
+
+    /**
+     * Print the login form, if required
+     *
+     * @return array of login options
+     */
+    public function print_login() {
+        $popup = new stdClass();
+        $popup->type = 'popup';
+        $url = $this->skydrive->get_login_url();
+        $popup->url = $url->out(false);
+        return array('login' => array($popup));
+    }
+
+    /**
+     * Given a path, and perhaps a search, get a list of files.
+     *
+     * See details on {@link http://docs.moodle.org/dev/Repository_plugins}
+     *
+     * @param string $path identifier for current path
+     * @param string $page the page number of file list
+     * @return array list of files including meta information as specified by parent.
+     */
+    public function get_listing($path='', $page = '') {
+        $ret = array();
+        $ret['dynload'] = true;
+        $ret['nosearch'] = true;
+        $ret['list'] = $this->skydrive->get_file_list($path);
+        return $ret;
+    }
+
+    /**
+     * Downloads a repository file and saves to a path.
+     *
+     * @param string $id identifier of file
+     * @param string $filename to save file as
+     * @return array with keys:
+     *          path: internal location of the file
+     *          url: URL to the source
+     */
+    public function get_file($id, $filename = '') {
+        $path = $this->prepare_file($filename);
+        return $this->skydrive->download_file($id, $path);
+    }
+
+    /**
+     * Return names of the options to display in the repository form
+     *
+     * @return array of option names
+     */
+    public static function get_type_option_names() {
+        return array('clientid', 'secret', 'pluginname');
+    }
+
+    /**
+     * Setup repistory form.
+     *
+     * @param moodleform $mform Moodle form (passed by reference)
+     * @param string $classname repository class name
+     */
+    public static function type_config_form($mform, $classname = 'repository') {
+        $a = new stdClass;
+        $a->callbackurl = microsoft_skydrive::callback_url()->out(false);
+        $mform->addElement('static', null, '', get_string('oauthinfo', 'repository_skydrive', $a));
+
+        parent::type_config_form($mform);
+        $strrequired = get_string('required');
+        $mform->addElement('text', 'clientid', get_string('clientid', 'repository_skydrive'));
+        $mform->addElement('text', 'secret', get_string('secret', 'repository_skydrive'));
+        $mform->addRule('clientid', $strrequired, 'required', null, 'client');
+        $mform->addRule('secret', $strrequired, 'required', null, 'client');
+        $mform->setType('clientid', PARAM_RAW_TRIMMED);
+        $mform->setType('secret', PARAM_RAW_TRIMMED);
+    }
+
+    /**
+     * Logout from repository instance and return
+     * login form.
+     *
+     * @return page to display
+     */
+    public function logout() {
+        $this->skydrive->log_out();
+        return $this->print_login();
+    }
+
+    /**
+     * This repository doesn't support global search.
+     *
+     * @return bool if supports global search
+     */
+    public function global_search() {
+        return false;
+    }
+
+    /**
+     * This repoistory supports any filetype.
+     *
+     * @return string '*' means this repository support any files
+     */
+    public function supported_filetypes() {
+        return '*';
+    }
+
+    /**
+     * This repostiory only supports internal files
+     *
+     * @return int return type bitmask supported
+     */
+    public function supported_returntypes() {
+        return FILE_INTERNAL;
+    }
+}
diff --git a/repository/skydrive/microsoftliveapi.php b/repository/skydrive/microsoftliveapi.php
new file mode 100644 (file)
index 0000000..e19e9a5
--- /dev/null
@@ -0,0 +1,183 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Functions for operating with the skydrive API
+ *
+ * @package    repository_skydrive
+ * @copyright  2012 Lancaster University Network Services Ltd
+ * @author     Dan Poltawski <dan.poltawski@luns.net.uk>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once($CFG->libdir.'/oauthlib.php');
+
+/**
+ * A helper class to access microsoft live resources using the api.
+ *
+ * This uses the microsfot API defined in
+ * http://msdn.microsoft.com/en-us/library/hh243648.aspx
+ *
+ * @package    repository_skydrive
+ * @copyright  2012 Lancaster University Network Services Ltd
+ * @author     Dan Poltawski <dan.poltawski@luns.net.uk>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class microsoft_skydrive extends oauth2_client {
+    /** @var string OAuth 2.0 scope */
+    const SCOPE = 'wl.skydrive';
+    /** @var string Base url to access API */
+    const API = 'https://apis.live.net/v5.0';
+
+    /**
+     * Construct a skydrive request object
+     *
+     * @param string $clientid client id for OAuth 2.0 provided by microsoft
+     * @param string $clientsecret secret for OAuth 2.0 provided by microsoft
+     * @param moodle_url $returnurl url to return to after succseful auth
+     */
+    public function __construct($clientid, $clientsecret, $returnurl) {
+        parent::__construct($clientid, $clientsecret, $returnurl, self::SCOPE);
+    }
+
+    /**
+     * Should HTTP GET be used instead of POST?
+     *
+     * The Microsoft API does not support POST, so we should use
+     * GET instead (with the auth_token passed as a GET param).
+     *
+     * @return bool true if GET should be used
+     */
+    protected function use_http_get() {
+        return true;
+    }
+
+    /**
+     * Returns the auth url for OAuth 2.0 request
+     * @return string the auth url
+     */
+    protected function auth_url() {
+        return 'https://oauth.live.com/authorize';
+    }
+
+    /**
+     * Returns the token url for OAuth 2.0 request
+     * @return string the auth url
+     */
+    protected function token_url() {
+        return 'https://oauth.live.com/token';
+    }
+
+    /**
+     * Downloads a file to a  file from skydrive using authenticated request
+     *
+     * @param string $id id of file
+     * @param string $path path to save file to
+     * @return array stucture for repository download_file
+     */
+    public function download_file($id, $path) {
+        $url = self::API."/${id}/content";
+        // Microsoft live redirects to the real download location..
+        $this->setopt(array('CURLOPT_FOLLOWLOCATION' => true, 'CURLOPT_MAXREDIRS' => 3));
+        $content = $this->get($url);
+        file_put_contents($path, $content);
+        return array('path'=>$path, 'url'=>$url);
+    }
+
+    /**
+     * Returns a list of files the user has formated for files api
+     *
+     * @param string $path the path which we are in
+     * @return mixed Array of files formated for fileapoi
+     */
+    public function get_file_list($path = '') {
+        global $OUTPUT;
+
+        if (empty($path)) {
+            $url = self::API."/me/skydrive/files/";
+        } else {
+            $url = self::API."/{$path}/files/";
+        }
+
+        $ret = json_decode($this->get($url));
+
+        if (isset($ret->error)) {
+            $this->log_out();
+            return false;
+        }
+
+        $files = array();
+
+        foreach ($ret->data as $file) {
+            switch($file->type) {
+                case 'folder':
+                    $files[] = array(
+                        'title' => $file->name,
+                        'path' => $file->id,
+                        'size' => 0,
+                        'date' => strtotime($file->updated_time),
+                        'thumbnail' => $OUTPUT->pix_url(file_folder_icon(90))->out(false),
+                        'children' => array(),
+                    );
+                    break;
+                case 'photo':
+                    $files[] = array(
+                        'title' => $file->name,
+                        'size' => $file->size,
+                        'date' => strtotime($file->updated_time),
+                        'thumbnail' => $file->picture,
+                        'source' => $file->id,
+                        'url' => $file->link,
+                    );
+                    break;
+                case 'video':
+                    $files[] = array(
+                        'title' => $file->name,
+                        'size' => $file->size,
+                        'date' => strtotime($file->updated_time),
+                        'thumbnail' => $file->picture,
+                        'source' => $file->id,
+                        'url' => $file->link,
+                    );
+                    break;
+                case 'audio':
+                    $files[] = array(
+                        'title' => $file->name,
+                        'size' => $file->size,
+                        'date' => strtotime($file->updated_time),
+                        'thumbnail' => $OUTPUT->pix_url(file_extension_icon($file->name, 90))->out(false),
+                        'source' => $file->id,
+                        'url' => $file->link,
+                    );
+                    break;
+                case 'file':
+                    $files[] = array(
+                        'title' => $file->name,
+                        'size' => $file->size,
+                        'date' => strtotime($file->updated_time),
+                        'thumbnail' => $OUTPUT->pix_url(file_extension_icon($file->name, 90))->out(false),
+                        'source' => $file->id,
+                        'url' => $file->link,
+                    );
+                    break;
+            }
+        }
+        return $files;
+    }
+}
diff --git a/repository/skydrive/pix/icon.png b/repository/skydrive/pix/icon.png
new file mode 100644 (file)
index 0000000..26b8549
Binary files /dev/null and b/repository/skydrive/pix/icon.png differ
diff --git a/repository/skydrive/version.php b/repository/skydrive/version.php
new file mode 100644 (file)
index 0000000..67fb444
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Version details for skydrive repository
+ *
+ * @package    repository_skydrive
+ * @copyright  2012 Lancaster University Network Services Ltd
+ * @author     Dan Poltawski <dan.poltawski@luns.net.uk>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+$plugin->version   = 2013062700;        // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2012062500;        // Requires this Moodle version.
+$plugin->component = 'repository_skydrive'; // Full name of the plugin (used for diagnostics).
+$plugin->release   = '1.2';
+$plugin->maturity  = MATURITY_STABLE;