From 7446284108b36f70e936a4cf5301943b74138ea4 Mon Sep 17 00:00:00 2001 From: Dan Poltawski Date: Sun, 13 May 2012 21:42:45 +0800 Subject: [PATCH] MDL-30740 repository: Add Microsoft Skydrive plugin MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 | 33 ++++ .../skydrive/lang/en/repository_skydrive.php | 30 +++ repository/skydrive/lib.php | 183 ++++++++++++++++++ repository/skydrive/microsoftliveapi.php | 183 ++++++++++++++++++ repository/skydrive/pix/icon.png | Bin 0 -> 5638 bytes repository/skydrive/version.php | 32 +++ 6 files changed, 461 insertions(+) create mode 100644 repository/skydrive/db/access.php create mode 100644 repository/skydrive/lang/en/repository_skydrive.php create mode 100644 repository/skydrive/lib.php create mode 100644 repository/skydrive/microsoftliveapi.php create mode 100644 repository/skydrive/pix/icon.png create mode 100644 repository/skydrive/version.php diff --git a/repository/skydrive/db/access.php b/repository/skydrive/db/access.php new file mode 100644 index 00000000000..6fe7ea25da2 --- /dev/null +++ b/repository/skydrive/db/access.php @@ -0,0 +1,33 @@ +. + +/** + * Capability definitions for skydrive repository + * + * @package repository_skydrive + * @copyright 2012 Lancaster University Network Services Ltd + * @author Dan Poltawski + * @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 index 00000000000..fe1c3fdef72 --- /dev/null +++ b/repository/skydrive/lang/en/repository_skydrive.php @@ -0,0 +1,30 @@ +. + +/** + * Language file definitions for skydrive repository + * + * @package repository_skydrive + * @copyright 2012 Lancaster University Network Services Ltd + * @author Dan Poltawski + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +$string['clientid'] = 'Client ID'; +$string['configplugin'] = 'Configure Microsoft Skydrive'; +$string['oauthinfo'] = '

To use this plugin, you must register your site with Microsoft.

As part of the registration process, you will need to enter the following URL as \'Redirect domain\':

{$a->callbackurl}

Once registered, you will be provided with a client ID and secret which can be entered here.

'; +$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 index 00000000000..fe827a19d18 --- /dev/null +++ b/repository/skydrive/lib.php @@ -0,0 +1,183 @@ +. + +/** + * Microsoft Live Skydrive Repository Plugin + * + * @package repository_skydrive + * @copyright 2012 Lancaster University Network Services Ltd + * @author Dan Poltawski + * @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 + * @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 index 00000000000..e19e9a50d5f --- /dev/null +++ b/repository/skydrive/microsoftliveapi.php @@ -0,0 +1,183 @@ +. + +/** + * Functions for operating with the skydrive API + * + * @package repository_skydrive + * @copyright 2012 Lancaster University Network Services Ltd + * @author Dan Poltawski + * @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 + * @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 index 0000000000000000000000000000000000000000..26b8549d077f7d3d450f7724b90e26f06af699fb GIT binary patch literal 5638 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 literal 0 HcmV?d00001 diff --git a/repository/skydrive/version.php b/repository/skydrive/version.php new file mode 100644 index 00000000000..67fb4446399 --- /dev/null +++ b/repository/skydrive/version.php @@ -0,0 +1,32 @@ +. + +/** + * Version details for skydrive repository + * + * @package repository_skydrive + * @copyright 2012 Lancaster University Network Services Ltd + * @author Dan Poltawski + * @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; -- 2.43.0