From 9b27ffa042d5a84d64283ea4a2e3bb8012f92c44 Mon Sep 17 00:00:00 2001
From: Dan Poltawski
Date: Sun, 13 May 2012 15:33:02 +0800
Subject: [PATCH 1/6] MDL-29857 - portfolio: Fix E_STRICT errors
---
lib/portfolio/forms.php | 6 +++---
portfolio/add.php | 3 ++-
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/lib/portfolio/forms.php b/lib/portfolio/forms.php
index ba408f78486..7b7c66908ed 100644
--- a/lib/portfolio/forms.php
+++ b/lib/portfolio/forms.php
@@ -107,7 +107,7 @@ final class portfolio_export_form extends moodleform {
* @param stdClass $data portfolio information from form data
* @return array
*/
- public function validation($data) {
+ public function validation($data, $files) {
$errors = array();
@@ -228,7 +228,7 @@ final class portfolio_admin_form extends moodleform {
* @param stdObject $data form data
* @return array
*/
- public function validation($data) {
+ public function validation($data, $files) {
global $DB;
$errors = array();
@@ -296,7 +296,7 @@ final class portfolio_user_form extends moodleform {
*
* @param stdClass $data form data
*/
- public function validation($data) {
+ public function validation($data, $files) {
$errors = $this->instance->user_config_validation($data);
diff --git a/portfolio/add.php b/portfolio/add.php
index b3c3982df0a..b5a1c4a4e25 100644
--- a/portfolio/add.php
+++ b/portfolio/add.php
@@ -221,7 +221,8 @@ if (!$exporter->get('instance')) {
throw new portfolio_export_exception($exporter, 'noavailableplugins', 'portfolio');
} else if (count($options) == 1) {
// no point displaying a form, just redirect.
- $instance = array_shift(array_keys($options));
+ $optionskeys = array_keys($options);
+ $instance = array_shift($optionskeys);
redirect($CFG->wwwroot . '/portfolio/add.php?id= ' . $exporter->get('id') . '&instance=' . $instance . '&sesskey=' . sesskey());
}
// be very selective about not including this unless we really need to
From f40f6c14b1d57eff6ddb0c8569c3ef5a03bf5893 Mon Sep 17 00:00:00 2001
From: Dan Poltawski
Date: Sun, 13 May 2012 12:57:41 +0800
Subject: [PATCH 2/6] MDL-32221 - googledocs: Add support for all file types.
Now google supports 'file' as well as converted formats.
---
lib/googleapi.php | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/lib/googleapi.php b/lib/googleapi.php
index a079ffb5d2f..51292947113 100644
--- a/lib/googleapi.php
+++ b/lib/googleapi.php
@@ -319,6 +319,10 @@ class google_docs {
$title = (string)$gdoc->title;
$source = (string)$gdoc->content[0]->attributes()->src;
break;
+ case 'file':
+ $title = (string)$gdoc->title;
+ $source = (string)$gdoc->content[0]->attributes()->src;
+ break;
}
if(!empty($source)){
From 469fb5d6722678c68b3e8711b08d1271d3d8c411 Mon Sep 17 00:00:00 2001
From: Dan Poltawski
Date: Mon, 14 May 2012 00:39:00 +0800
Subject: [PATCH 3/6] MDL-29857 - lib: Add an OAuth 2.0 client
A generic OAuth 2.0 for the web application flow, tested against
microsoft and google apis.
Added a callback endpoint for requests so that clients can use a single
endpoint (without GET params). I put this in /admin/ as I expect some
sites will have .htaccess denying access to /lib/.
---
admin/oauth2callback.php | 38 ++++++
lib/oauthlib.php | 262 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 299 insertions(+), 1 deletion(-)
create mode 100644 admin/oauth2callback.php
diff --git a/admin/oauth2callback.php b/admin/oauth2callback.php
new file mode 100644
index 00000000000..364c0023de0
--- /dev/null
+++ b/admin/oauth2callback.php
@@ -0,0 +1,38 @@
+.
+
+/**
+ * An oauth2 redirection endpoint which can be used for an application:
+ * http://tools.ietf.org/html/draft-ietf-oauth-v2-26#section-3.1.2
+ *
+ * This is used because some oauth servers will not allow a redirect urls
+ * with get params (like repository callback) and that needs to be called
+ * using the state param.
+ *
+ * @package core
+ * @copyright 2012 Dan Poltawski
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once(dirname(dirname(__FILE__)).'/config.php');
+
+// The authorization code generated by the authorization server.
+$code = required_param('code', PARAM_RAW);
+// The state parameter we've given (used in moodle as a redirect url).
+$state = required_param('state', PARAM_URL);
+
+redirect(new moodle_url($state, array('code' => $code)));
diff --git a/lib/oauthlib.php b/lib/oauthlib.php
index 36ee14e9f9b..b4aa15b7500 100644
--- a/lib/oauthlib.php
+++ b/lib/oauthlib.php
@@ -1,5 +1,4 @@
.
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once($CFG->libdir.'/filelib.php');
+
/**
* OAuth helper class
*
@@ -349,3 +353,259 @@ class oauth_helper {
return md5($mt . $rand);
}
}
+
+/**
+ * OAuth 2.0 Client for using web access tokens.
+ *
+ * http://tools.ietf.org/html/draft-ietf-oauth-v2-22
+ *
+ * @package core
+ * @copyright Dan Poltawski
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+abstract class oauth2_client extends curl {
+ /** var string client identifier issued to the client */
+ private $clientid = '';
+ /** var string The client secret. */
+ private $clientsecret = '';
+ /** var string URL to return to after authenticating */
+ private $returnurl = '';
+ /** var string scope of the authentication request */
+ private $scope = '';
+ /** var stdClass access token object */
+ private $accesstoken = null;
+
+ /**
+ * Returns the auth url for OAuth 2.0 request
+ * @return string the auth url
+ */
+ abstract protected function auth_url();
+
+ /**
+ * Returns the token url for OAuth 2.0 request
+ * @return string the auth url
+ */
+ abstract protected function token_url();
+
+ /**
+ * Constructor.
+ *
+ * @param string $clientid
+ * @param string $clientsecret
+ * @param string $returnurl
+ * @param string $scope
+ */
+ public function __construct($clientid, $clientsecret, $returnurl, $scope) {
+ parent::__construct();
+ $this->clientid = $clientid;
+ $this->clientsecret = $clientsecret;
+ $this->returnurl = $returnurl;
+ $this->scope = $scope;
+ $this->accesstoken = $this->get_stored_token();
+ }
+
+ /**
+ * Is the user logged in? Note that if this is called
+ * after the first part of the authorisation flow the token
+ * is upgraded to an accesstoken.
+ *
+ * @return boolean true if logged in
+ */
+ public function is_logged_in() {
+ // Has the token expired?
+ if (isset($this->accesstoken->expires) && time() >= $this->accesstoken->expires) {
+ $this->log_out();
+ return false;
+ }
+
+ // We have a token so we are logged in.
+ if (isset($this->accesstoken->token)) {
+ return true;
+ }
+
+ // If we've been passed then authorization code generated by the
+ // authorization server try and upgrade the token to an access token.
+ $code = optional_param('code', null, PARAM_RAW);
+ if ($code && $this->upgrade_token($code)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Callback url where the request is returned to.
+ *
+ * @return moodle_url url of callback
+ */
+ public static function callback_url() {
+ global $CFG;
+
+ return new moodle_url('/admin/oauth2callback.php');
+ }
+
+ /**
+ * Returns the login link for this oauth request
+ *
+ * @return moodle_url login url
+ */
+ public function get_login_url() {
+
+ $callbackurl = self::callback_url();
+ $url = new moodle_url($this->auth_url(),
+ array('client_id' => $this->clientid,
+ 'response_type' => 'code',
+ 'redirect_uri' => $callbackurl->out(false),
+ 'state' => $this->returnurl,
+ 'scope' => $this->scope,
+ ));
+
+ return $url;
+ }
+
+ /**
+ * Upgrade a authorization token from oauth 2.0 to an access token
+ *
+ * @param string $code the code returned from the oauth authenticaiton
+ * @return boolean true if token is upgraded succesfully
+ */
+ public function upgrade_token($code) {
+ $callbackurl = self::callback_url();
+ $params = array('client_id' => $this->clientid,
+ 'client_secret' => $this->clientsecret,
+ 'grant_type' => 'authorization_code',
+ 'code' => $code,
+ 'redirect_uri' => $callbackurl->out(false),
+ );
+
+ // Requests can either use http GET or POST.
+ if ($this->use_http_get()) {
+ $response = $this->get($this->token_url(), $params);
+ } else {
+ $response = $this->post($this->token_url(), $params);
+ }
+
+ if (!$this->info['http_code'] === 200) {
+ throw new moodle_exception('Could not upgrade oauth token');
+ }
+
+ $r = json_decode($response);
+
+ if (!isset($r->access_token)) {
+ return false;
+ }
+
+ // Store the token an expiry time.
+ $accesstoken = new stdClass;
+ $accesstoken->token = $r->access_token;
+ $accesstoken->expires = (time() + ($r->expires_in - 10)); // Expires 10 seconds before actual expiry.
+ $this->store_token($accesstoken);
+
+ return true;
+ }
+
+ /**
+ * Logs out of a oauth request, clearing any stored tokens
+ */
+ public function log_out() {
+ $this->store_token(null);
+ }
+
+ /**
+ * Make a HTTP request, adding the access token we have
+ *
+ * @param string $url The URL to request
+ * @param array $options
+ * @return bool
+ */
+ protected function request($url, $options = array()) {
+ $murl = new moodle_url($url);
+
+ if ($this->accesstoken) {
+ if ($this->use_http_get()) {
+ // If using HTTP GET add as a parameter.
+ $murl->param('access_token', $this->accesstoken->token);
+ } else {
+ $this->setHeader('Authorization: Bearer '.$this->accesstoken->token);
+ }
+ }
+
+ return parent::request($murl->out(false), $options);
+ }
+
+ /**
+ * Multiple HTTP Requests
+ * This function could run multi-requests in parallel.
+ *
+ * @param array $requests An array of files to request
+ * @param array $options An array of options to set
+ * @return array An array of results
+ */
+ protected function multi($requests, $options = array()) {
+ if ($this->accesstoken) {
+ $this->setHeader('Authorization: Bearer '.$this->accesstoken->token);
+ }
+ return parent::multi($requests, $options);
+ }
+
+ /**
+ * Returns the tokenname for the access_token to be stored
+ * through multiple requests.
+ *
+ * The default implentation is to use the classname combiend
+ * with the scope.
+ *
+ * @return string tokenname for prefernce storage
+ */
+ protected function get_tokenname() {
+ // This is unusual but should work for most purposes.
+ return get_class($this).'-'.md5($this->scope);
+ }
+
+ /**
+ * Store a token between requests. Currently uses
+ * session named by get_tokenname
+ *
+ * @param stdClass|null $token token object to store or null to clear
+ */
+ protected function store_token($token) {
+ global $SESSION;
+
+ $this->accesstoken = $token;
+ $name = $this->get_tokenname();
+
+ if ($token !== null) {
+ $SESSION->{$name} = $token;
+ } else {
+ unset($SESSION->{$name});
+ }
+ }
+
+ /**
+ * Retrieve a token stored.
+ *
+ * @return stdClass|null token object
+ */
+ protected function get_stored_token() {
+ global $SESSION;
+
+ $name = $this->get_tokenname();
+
+ if (isset($SESSION->{$name})) {
+ return $SESSION->{$name};
+ }
+
+ return null;
+ }
+
+ /**
+ * Should HTTP GET be used instead of POST?
+ * Some APIs do not support POST and want oauth to 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 false;
+ }
+}
From 4560fd1b669ad65149d8ca19fac9f4210358bd11 Mon Sep 17 00:00:00 2001
From: Dan Poltawski
Date: Mon, 14 May 2012 00:42:24 +0800
Subject: [PATCH 4/6] MDL-29857 - google apis: Convert to OAuth 2.0
Updated the various plugins to use OAuth 2.0 for authentication
against google apis. Google are phasing out AuthSub and pushing OAuth as
the replacement.
This changes repository_googledocs, repository_picasa,
portfolio_googledocs and portfolio_picasa
The token for requests is now stored in session rather than a user
prefence and it persists less but doesn't bother the user more than
necessary.
The google docs portfolio plugin is converted to use resumable upload
API as this appears to be what Google have replaced this with.
Unfortunately unlike authsub OAuth will require some setup by admins,
this is linked as a docs page.
---
lib/googleapi.php | 515 ++++++------------
.../lang/en/portfolio_googledocs.php | 4 +-
portfolio/googledocs/lib.php | 128 ++---
portfolio/googledocs/version.php | 6 +-
portfolio/picasa/lang/en/portfolio_picasa.php | 4 +-
portfolio/picasa/lib.php | 112 ++--
portfolio/picasa/version.php | 6 +-
.../googledocs/db/upgrade.php | 28 +-
.../lang/en/repository_googledocs.php | 7 +-
repository/googledocs/lib.php | 106 ++--
repository/googledocs/version.php | 6 +-
.../picasa/db/upgrade.php | 26 +-
.../picasa/lang/en/repository_picasa.php | 6 +-
repository/picasa/lib.php | 96 ++--
repository/picasa/version.php | 6 +-
15 files changed, 428 insertions(+), 628 deletions(-)
rename portfolio/picasa/db/events.php => repository/googledocs/db/upgrade.php (58%)
rename portfolio/googledocs/db/events.php => repository/picasa/db/upgrade.php (58%)
diff --git a/lib/googleapi.php b/lib/googleapi.php
index 51292947113..5994dd382d8 100644
--- a/lib/googleapi.php
+++ b/lib/googleapi.php
@@ -1,276 +1,62 @@
.
+
/**
- * Moodle - Modular Object-Oriented Dynamic Learning Environment
- * http://moodle.org
- * Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com
+ * Simple implementation of some Google API functions for Moodle.
*
- * This program 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 2 of the License, or
- * (at your option) any later version.
+ * @package core
+ * @copyright Dan Poltawski
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once($CFG->libdir.'/filelib.php');
+require_once($CFG->libdir.'/oauthlib.php');
+
+/**
+ * Class for manipulating google documents through the google data api.
*
- * This program 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 this program. If not, see .
+ * Docs for this can be found here:
+ * {@link http://code.google.com/apis/documents/docs/2.0/developers_guide_protocol.html}
*
* @package core
* @subpackage lib
* @copyright Dan Poltawski
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- *
- * Simple implementation of some Google API functions for Moodle.
- */
-
-defined('MOODLE_INTERNAL') || die();
-
- /** Include essential file */
-require_once($CFG->libdir.'/filelib.php');
-
-/**
- * Base class for google authenticated http requests
- *
- * Most Google API Calls required that requests are sent with an
- * Authorization header + token. This class extends the curl class
- * to aid this
- *
- * @package moodlecore
- * @subpackage lib
- * @copyright Dan Poltawski
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-abstract class google_auth_request extends curl {
- protected $token = '';
- private $persistantheaders = array();
-
- // Must be overridden with the authorization header name
- public static function get_auth_header_name() {
- throw new coding_exception('get_auth_header_name() method needs to be overridden in each subclass of google_auth_request');
- }
-
- protected function request($url, $options = array()){
- if($this->token){
- // Adds authorisation head to a request so that it can be authentcated
- $this->setHeader('Authorization: '. $this->get_auth_header_name().'"'.$this->token.'"');
- }
-
- foreach($this->persistantheaders as $h){
- $this->setHeader($h);
- }
-
- $ret = parent::request($url, $options);
- // reset headers for next request
- $this->header = array();
- return $ret;
- }
-
- protected function multi($requests, $options = array()) {
- if($this->token){
- // Adds authorisation head to a request so that it can be authentcated
- $this->setHeader('Authorization: '. $this->get_auth_header_name().'"'.$this->token.'"');
- }
-
- foreach($this->persistantheaders as $h){
- $this->setHeader($h);
- }
-
- $ret = parent::multi($requests, $options);
- // reset headers for next request
- $this->header = array();
- return $ret;
- }
-
- public function get_sessiontoken(){
- return $this->token;
- }
-
- public function add_persistant_header($header){
- $this->persistantheaders[] = $header;
- }
-}
-
-/*******
- * The following two classes are usd to implement AuthSub google
- * authtentication, as documented here:
- * http://code.google.com/apis/accounts/docs/AuthSub.html
- *******/
-
-/**
- * Used to uprade a google AuthSubRequest one-time token into
- * a session token which can be used long term.
- *
- * @package moodlecore
- * @subpackage lib
- * @copyright Dan Poltawski
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class google_authsub_request extends google_auth_request {
- const AUTHSESSION_URL = 'https://www.google.com/accounts/AuthSubSessionToken';
-
- /**
- * Constructor. Calls constructor of its parents
- *
- * @param string $authtoken The token to upgrade to a session token
- */
- public function __construct($authtoken){
- parent::__construct();
- $this->token = $authtoken;
- }
-
- /**
- * Requests a long-term session token from google based on the
- *
- * @return string Sub-Auth token
- */
- public function get_session_token(){
- $content = $this->get(google_authsub_request::AUTHSESSION_URL);
-
- if( preg_match('/token=(.*)/i', $content, $matches) ){
- return $matches[1];
- }else{
- throw new moodle_exception('could not upgrade google authtoken to session token');
- }
- }
-
- public static function get_auth_header_name(){
- return 'AuthSub token=';
- }
-}
-
-/**
- * Allows http calls using google subauth authorisation
- *
- * @package moodlecore
- * @subpackage lib
- * @copyright Dan Poltawski
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class google_authsub extends google_auth_request {
- const LOGINAUTH_URL = 'https://www.google.com/accounts/AuthSubRequest';
- const VERIFY_TOKEN_URL = 'https://www.google.com/accounts/AuthSubTokenInfo';
- const REVOKE_TOKEN_URL = 'https://www.google.com/accounts/AuthSubRevokeToken';
-
- /**
- * Constructor, allows subauth requests using the response from an initial
- * AuthSubRequest or with the subauth long-term token. Note that constructing
- * this object without a valid token will cause an exception to be thrown.
- *
- * @param string $sessiontoken A long-term subauth session token
- * @param string $authtoken A one-time auth token wich is used to upgrade to session token
- * @param mixed @options Options to pass to the base curl object
- */
- public function __construct($sessiontoken = '', $authtoken = '', $options = array()){
- parent::__construct($options);
-
- if( $authtoken ){
- $gauth = new google_authsub_request($authtoken);
- $sessiontoken = $gauth->get_session_token();
- }
-
- $this->token = $sessiontoken;
- if(! $this->valid_token() ){
- throw new moodle_exception('Invalid subauth token');
- }
- }
-
- /**
- * Tests if a subauth token used is valid
- *
- * @return boolean true if token valid
- */
- public function valid_token(){
- $this->get(google_authsub::VERIFY_TOKEN_URL);
-
- if($this->info['http_code'] === 200){
- return true;
- }else{
- return false;
- }
- }
-
- /**
- * Calls googles api to revoke the subauth token
- *
- * @return boolean Returns true if token succesfully revoked
- */
- public function revoke_session_token(){
- $this->get(google_authsub::REVOKE_TOKEN_URL);
-
- if($this->info['http_code'] === 200){
- $this->token = '';
- return true;
- }else{
- return false;
- }
- }
-
- /**
- * Creates a login url for subauth request
- *
- * @param string $returnaddr The address which the user should be redirected to recieve the token
- * @param string $realm The google realm which is access is being requested
- * @return string URL to bounce the user to
- */
- public static function login_url($returnaddr, $realm){
- $uri = google_authsub::LOGINAUTH_URL.'?next='
- .urlencode($returnaddr)
- .'&scope='
- .urlencode($realm)
- .'&session=1&secure=0';
-
- return $uri;
- }
-
- public static function get_auth_header_name(){
- return 'AuthSub token=';
- }
-}
-
-/**
- * Class for manipulating google documents through the google data api
- * Docs for this can be found here:
- * {@link http://code.google.com/apis/documents/docs/2.0/developers_guide_protocol.html}
- *
- * @package moodlecore
- * @subpackage lib
- * @copyright Dan Poltawski
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class google_docs {
- // need both docs and the spreadsheets realm
+ /** @var string Realm for authentication, need both docs and spreadsheet realm */
const REALM = 'https://docs.google.com/feeds/ https://spreadsheets.google.com/feeds/ https://docs.googleusercontent.com/';
+ /** @var string Document list url */
const DOCUMENTFEED_URL = 'https://docs.google.com/feeds/default/private/full';
- const USER_PREF_NAME = 'google_authsub_sesskey';
+ /** @var string Upload url */
+ const UPLOAD_URL = 'https://docs.google.com/feeds/upload/create-session/default/private/full?convert=false';
- private $google_curl = null;
+ /** @var google_oauth oauth curl class for making authenticated requests */
+ private $googleoauth = null;
/**
* Constructor.
*
- * @param object A google_auth_request object which can be used to do http requests
+ * @param google_oauth $googleoauth oauth curl class for making authenticated requests
*/
- public function __construct($google_curl){
- if(is_a($google_curl, 'google_auth_request')){
- $this->google_curl = $google_curl;
- $this->google_curl->add_persistant_header('GData-Version: 3.0');
- }else{
- throw new moodle_exception('Google Curl Request object not given');
- }
- }
-
- public static function get_sesskey($userid){
- return get_user_preferences(google_docs::USER_PREF_NAME, false, $userid);
- }
-
- public static function set_sesskey($value, $userid){
- return set_user_preference(google_docs::USER_PREF_NAME, $value, $userid);
- }
-
- public static function delete_sesskey($userid){
- return unset_user_preference(google_docs::USER_PREF_NAME, $userid);
+ public function __construct(google_oauth $googleoauth) {
+ $this->googleoauth = $googleoauth;
+ $this->googleoauth->setHeader('GData-Version: 3.0');
}
/**
@@ -279,21 +65,19 @@ class google_docs {
* @param string $search A search string to do full text search on the documents
* @return mixed Array of files formated for fileapoi
*/
- #FIXME
- public function get_file_list($search = ''){
+ public function get_file_list($search = '') {
global $CFG, $OUTPUT;
- $url = google_docs::DOCUMENTFEED_URL;
+ $url = self::DOCUMENTFEED_URL;
- if($search){
+ if ($search) {
$url.='?q='.urlencode($search);
}
- $content = $this->google_curl->get($url);
+ $content = $this->googleoauth->get($url);
$xml = new SimpleXMLElement($content);
-
$files = array();
- foreach($xml->entry as $gdoc){
+ foreach ($xml->entry as $gdoc) {
$docid = (string) $gdoc->children('http://schemas.google.com/g/2005')->resourceId;
list($type, $docid) = explode(':', $docid);
@@ -325,7 +109,7 @@ class google_docs {
break;
}
- if(!empty($source)){
+ if (!empty($source)) {
$files[] = array( 'title' => $title,
'url' => "{$gdoc->link[0]->attributes()->href}",
'source' => $source,
@@ -344,71 +128,98 @@ class google_docs {
* @param object $file File object
* @return boolean True on success
*/
- public function send_file($file){
- $this->google_curl->setHeader("Content-Length: ". $file->get_filesize());
- $this->google_curl->setHeader("Content-Type: ". $file->get_mimetype());
- $this->google_curl->setHeader("Slug: ". $file->get_filename());
+ public function send_file($file) {
+ // First we create the 'resumable upload request'.
+ $this->googleoauth->setHeader("Content-Length: 0");
+ $this->googleoauth->setHeader("X-Upload-Content-Length: ". $file->get_filesize());
+ $this->googleoauth->setHeader("X-Upload-Content-Type: ". $file->get_mimetype());
+ $this->googleoauth->setHeader("Slug: ". $file->get_filename());
+ $this->googleoauth->post(self::UPLOAD_URL);
- $this->google_curl->post(google_docs::DOCUMENTFEED_URL, $file->get_content());
+ if ($this->googleoauth->info['http_code'] !== 200) {
+ throw new moodle_exception('Cantpostupload');
+ }
- if($this->google_curl->info['http_code'] === 201){
+ // Now we http PUT the file in the location returned.
+ $location = $this->googleoauth->response['Location'];
+ if (empty($location)) {
+ throw new moodle_exception('Nouploadlocation');
+ }
+
+ // Reset the curl object for actually sending the file.
+ $this->googleoauth->clear_headers();
+ $this->googleoauth->setHeader("Content-Length: ". $file->get_filesize());
+ $this->googleoauth->setHeader("Content-Type: ". $file->get_mimetype());
+
+ // We can't get a filepointer, so have to copy the file..
+ $tmproot = make_temp_directory('googledocsuploads');
+ $tmpfilepath = $tmproot.'/'.$file->get_contenthash();
+ $file->copy_content_to($tmpfilepath);
+
+ // HTTP PUT the file.
+ $this->googleoauth->put($location, array('file'=>$tmpfilepath));
+
+ // Remove the temporary file we created..
+ unlink($tmpfilepath);
+
+ if ($this->googleoauth->info['http_code'] === 201) {
return true;
- }else{
+ } else {
return false;
}
}
- public function download_file($url, $fp){
- return $this->google_curl->download(array( array('url'=>$url, 'file' => $fp) ));
+ /**
+ * Downloads a file using authentication
+ *
+ * @param string $url url of file
+ * @param string $path path to save file to
+ * @return array stucture for repository download_file
+ */
+ public function download_file($url, $path) {
+ $content = $this->googleoauth->get($url);
+ file_put_contents($path, $content);
+ return array('path'=>$path, 'url'=>$url);
}
}
/**
- * Class for manipulating picasa through the google data api
+ * Class for manipulating picasa through the google data api.
+ *
* Docs for this can be found here:
* {@link http://code.google.com/apis/picasaweb/developers_guide_protocol.html}
*
- * @package moodlecore
- * @subpackage lib
+ * @package core
* @copyright Dan Poltawski
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class google_picasa {
+ /** @var string Realm for authentication */
const REALM = 'http://picasaweb.google.com/data/';
- const USER_PREF_NAME = 'google_authsub_sesskey_picasa';
+ /** @var string Upload url */
const UPLOAD_LOCATION = 'https://picasaweb.google.com/data/feed/api/user/default/albumid/default';
+ /** @var string photo list url */
const ALBUM_PHOTO_LIST = 'https://picasaweb.google.com/data/feed/api/user/default/albumid/';
+ /** @var string search url */
const PHOTO_SEARCH_URL = 'https://picasaweb.google.com/data/feed/api/user/default?kind=photo&q=';
+ /** @var string album list url */
const LIST_ALBUMS_URL = 'https://picasaweb.google.com/data/feed/api/user/default';
+ /** @var string manage files url */
const MANAGE_URL = 'http://picasaweb.google.com/';
- private $google_curl = null;
+ /** @var google_oauth oauth curl class for making authenticated requests */
+ private $googleoauth = null;
+ /** @var string Last album name retrievied */
private $lastalbumname = null;
/**
* Constructor.
*
- * @param object A google_auth_request object which can be used to do http requests
+ * @param google_oauth $googleoauth oauth curl class for making authenticated requests
*/
- public function __construct($google_curl){
- if(is_a($google_curl, 'google_auth_request')){
- $this->google_curl = $google_curl;
- $this->google_curl->add_persistant_header('GData-Version: 2');
- }else{
- throw new moodle_exception('Google Curl Request object not given');
- }
- }
-
- public static function get_sesskey($userid){
- return get_user_preferences(google_picasa::USER_PREF_NAME, false, $userid);
- }
-
- public static function set_sesskey($value, $userid){
- return set_user_preference(google_picasa::USER_PREF_NAME, $value, $userid);
- }
-
- public static function delete_sesskey($userid){
- return unset_user_preference(google_picasa::USER_PREF_NAME, $userid);
+ public function __construct(google_oauth $googleoauth) {
+ $this->googleoauth = $googleoauth;
+ $this->googleoauth->setHeader('GData-Version: 2');
}
/**
@@ -417,16 +228,16 @@ class google_picasa {
* @param object $file File object
* @return boolean True on success
*/
- public function send_file($file){
- $this->google_curl->setHeader("Content-Length: ". $file->get_filesize());
- $this->google_curl->setHeader("Content-Type: ". $file->get_mimetype());
- $this->google_curl->setHeader("Slug: ". $file->get_filename());
+ public function send_file($file) {
+ $this->googleoauth->setHeader("Content-Length: ". $file->get_filesize());
+ $this->googleoauth->setHeader("Content-Type: ". $file->get_mimetype());
+ $this->googleoauth->setHeader("Slug: ". $file->get_filename());
- $this->google_curl->post(google_picasa::UPLOAD_LOCATION, $file->get_content());
+ $this->googleoauth->post(self::UPLOAD_LOCATION, $file->get_content());
- if($this->google_curl->info['http_code'] === 201){
+ if ($this->googleoauth->info['http_code'] === 201) {
return true;
- }else{
+ } else {
return false;
}
}
@@ -439,10 +250,10 @@ class google_picasa {
* @param string $path The path to files (assumed to be albumid)
* @return mixed $files A list of files for the file picker
*/
- public function get_file_list($path = ''){
- if(!$path){
+ public function get_file_list($path = '') {
+ if (!$path) {
return $this->get_albums();
- }else{
+ } else {
return $this->get_album_photos($path);
}
}
@@ -453,8 +264,8 @@ class google_picasa {
* @param int $albumid Photo album to list photos from
* @return mixed $files A list of files for the file picker
*/
- public function get_album_photos($albumid){
- $albumcontent = $this->google_curl->get(google_picasa::ALBUM_PHOTO_LIST.$albumid);
+ public function get_album_photos($albumid) {
+ $albumcontent = $this->googleoauth->get(self::ALBUM_PHOTO_LIST.$albumid);
return $this->get_photo_details($albumcontent);
}
@@ -475,8 +286,8 @@ class google_picasa {
* @param string $query Search terms
* @return mixed $files A list of files for the file picker
*/
- public function do_photo_search($query){
- $content = $this->google_curl->get(google_picasa::PHOTO_SEARCH_URL.htmlentities($query));
+ public function do_photo_search($query) {
+ $content = $this->googleoauth->get(self::PHOTO_SEARCH_URL.htmlentities($query));
return $this->get_photo_details($content);
}
@@ -487,17 +298,17 @@ class google_picasa {
*
* @return mixes $files Array in the format get_listing uses for folders
*/
- public function get_albums(){
- $content = $this->google_curl->get(google_picasa::LIST_ALBUMS_URL);
+ public function get_albums() {
+ $content = $this->googleoauth->get(self::LIST_ALBUMS_URL);
$xml = new SimpleXMLElement($content);
$files = array();
- foreach($xml->entry as $album){
+ foreach ($xml->entry as $album) {
$gphoto = $album->children('http://schemas.google.com/photos/2007');
$mediainfo = $album->children('http://search.yahoo.com/mrss/');
- //hacky...
+ // Hacky...
$thumbnailinfo = $mediainfo->group->thumbnail[0]->attributes();
$files[] = array( 'title' => (string) $album->title,
@@ -505,7 +316,7 @@ class google_picasa {
'size' => (int) $gphoto->bytesUsed,
'path' => (string) $gphoto->id,
'thumbnail' => (string) $thumbnailinfo['url'],
- 'thumbnail_width' => 160, // 160 is the native maximum dimension
+ 'thumbnail_width' => 160, // 160 is the native maximum dimension.
'thumbnail_height' => 160,
'children' => array(),
);
@@ -522,22 +333,22 @@ class google_picasa {
* @param string $rawxml XML from picasa api
* @return mixed $files A list of files for the file picker
*/
- public function get_photo_details($rawxml){
+ public function get_photo_details($rawxml) {
$xml = new SimpleXMLElement($rawxml);
$this->lastalbumname = (string)$xml->title;
$files = array();
- foreach($xml->entry as $photo){
+ foreach ($xml->entry as $photo) {
$gphoto = $photo->children('http://schemas.google.com/photos/2007');
$mediainfo = $photo->children('http://search.yahoo.com/mrss/');
$fullinfo = $mediainfo->group->content->attributes();
- //hacky...
+ // Hacky...
$thumbnailinfo = $mediainfo->group->thumbnail[0]->attributes();
- // Derive the nicest file name we can
+ // Derive the nicest file name we can.
if (!empty($mediainfo->group->description)) {
$title = shorten_text((string)$mediainfo->group->description, 20, false, '');
$title = clean_filename($title).'.jpg';
@@ -551,7 +362,7 @@ class google_picasa {
'size' => (int) $gphoto->size,
'path' => $gphoto->albumid.'/'.$gphoto->id,
'thumbnail' => (string) $thumbnailinfo['url'],
- 'thumbnail_width' => 72, // 72 is the native maximum dimension
+ 'thumbnail_width' => 72, // 72 is the native maximum dimension.
'thumbnail_height' => 72,
'source' => (string) $fullinfo['url'],
'url' => (string) $fullinfo['url']
@@ -560,54 +371,36 @@ class google_picasa {
return $files;
}
-
}
/**
- * Beginings of an implementation of Clientogin authenticaton for google
- * accounts as documented here:
- * {@link http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html#ClientLogin}
+ * OAuth 2.0 client for Google Services
*
- * With this authentication we have to accept a username and password and to post
- * it to google. Retrieving a token for use afterwards.
- *
- * @package moodlecore
- * @subpackage lib
- * @copyright Dan Poltawski
+ * @package core
+ * @copyright 2012 Dan Poltawski
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-class google_authclient extends google_auth_request {
- const LOGIN_URL = 'https://www.google.com/accounts/ClientLogin';
-
- public function __construct($sessiontoken = '', $username = '', $password = '', $options = array() ){
- parent::__construct($options);
-
- if($username and $password){
- $param = array(
- 'accountType'=>'GOOGLE',
- 'Email'=>$username,
- 'Passwd'=>$password,
- 'service'=>'writely'
- );
-
- $content = $this->post(google_authclient::LOGIN_URL, $param);
-
- if( preg_match('/auth=(.*)/i', $content, $matches) ){
- $sessiontoken = $matches[1];
- }else{
- throw new moodle_exception('could not upgrade authtoken');
- }
-
- }
-
- if($sessiontoken){
- $this->token = $sessiontoken;
- }else{
- throw new moodle_exception('no session token specified');
- }
+class google_oauth extends oauth2_client {
+ /**
+ * Returns the auth url for OAuth 2.0 request
+ * @return string the auth url
+ */
+ protected function auth_url() {
+ return 'https://accounts.google.com/o/oauth2/auth';
}
- public static function get_auth_header_name(){
- return 'GoogleLogin auth=';
+ /**
+ * Returns the token url for OAuth 2.0 request
+ * @return string the auth url
+ */
+ protected function token_url() {
+ return 'https://accounts.google.com/o/oauth2/token';
+ }
+
+ /**
+ * Clear any headers in the curl object
+ */
+ public function clear_headers() {
+ $this->header = array();
}
}
diff --git a/portfolio/googledocs/lang/en/portfolio_googledocs.php b/portfolio/googledocs/lang/en/portfolio_googledocs.php
index f1c9262f823..0fb864dac40 100644
--- a/portfolio/googledocs/lang/en/portfolio_googledocs.php
+++ b/portfolio/googledocs/lang/en/portfolio_googledocs.php
@@ -1,5 +1,4 @@
To use the google docs portfolio you must be registered with Google. Instructions for registing your installation with Google are described in Moodle Docs. The redirect url should be set to:
{$a->callbackurl}
';
$string['noauthtoken'] = 'An authentication token has not been recieved from google. Please ensure you are allowing moodle to access your google account';
$string['nosessiontoken'] = 'A session token does not exist preventing export to google.';
$string['pluginname'] = 'Google Docs';
$string['sendfailed'] = 'The file {$a} failed to transfer to google';
+$string['secret'] = 'Secret';
diff --git a/portfolio/googledocs/lib.php b/portfolio/googledocs/lib.php
index 2223f9d4831..c641f096df1 100644
--- a/portfolio/googledocs/lib.php
+++ b/portfolio/googledocs/lib.php
@@ -1,4 +1,19 @@
.
+
/**
* Google Documents Portfolio Plugin
*
@@ -9,18 +24,10 @@ require_once($CFG->libdir.'/portfolio/plugin.php');
require_once($CFG->libdir.'/googleapi.php');
class portfolio_plugin_googledocs extends portfolio_plugin_push_base {
- private $sessiontoken;
+ private $googleoauth = null;
public function supported_formats() {
- return array(
- PORTFOLIO_FORMAT_PLAINHTML,
- PORTFOLIO_FORMAT_IMAGE,
- PORTFOLIO_FORMAT_TEXT,
- PORTFOLIO_FORMAT_PDF,
- PORTFOLIO_FORMAT_DOCUMENT,
- PORTFOLIO_FORMAT_PRESENTATION,
- PORTFOLIO_FORMAT_SPREADSHEET
- );
+ return array(PORTFOLIO_FORMAT_FILE);
}
public static function get_name() {
@@ -28,29 +35,27 @@ class portfolio_plugin_googledocs extends portfolio_plugin_push_base {
}
public function prepare_package() {
- // we send the files as they are, no prep required
+ // We send the files as they are, no prep required.
return true;
}
- public function get_interactive_continue_url(){
+ public function get_interactive_continue_url() {
return 'http://docs.google.com/';
}
public function expected_time($callertime) {
- // we trust what the portfolio says
+ // We trust what the portfolio says.
return $callertime;
}
public function send_package() {
-
- if(!$this->sessiontoken){
- throw new portfolio_plugin_exception('nosessiontoken', 'portfolio_googledocs');
+ if (!$this->googleoauth) {
+ throw new portfolio_plugin_exception('noauthtoken', 'portfolio_googledocs');
}
- $gdocs = new google_docs(new google_authsub($this->sessiontoken));
-
+ $gdocs = new google_docs($this->googleoauth);
foreach ($this->exporter->get_tempfiles() as $file) {
- if(!$gdocs->send_file($file)){
+ if (!$gdocs->send_file($file)) {
throw new portfolio_plugin_exception('sendfailed', 'portfolio_gdocs', $file->get_filename());
}
}
@@ -62,20 +67,12 @@ class portfolio_plugin_googledocs extends portfolio_plugin_push_base {
return false;
}
- $sesskey = google_docs::get_sesskey($this->get('user')->id);
-
- if($sesskey){
- try{
- $gauth = new google_authsub($sesskey);
- $this->sessiontoken = $sesskey;
- return false;
- }catch(Exception $e){
- // sesskey is not valid, delete store and re-auth
- google_docs::delete_sesskey($this->get('user')->id);
- }
+ $this->initialize_oauth();
+ if ($this->googleoauth->is_logged_in()) {
+ return false;
+ } else {
+ return $this->googleoauth->get_login_url();
}
-
- return google_authsub::login_url($CFG->wwwroot.'/portfolio/add.php?postcontrol=1&id=' . $this->exporter->get('id') . '&sesskey=' . sesskey(), google_docs::REALM);
}
public function post_control($stage, $params) {
@@ -83,43 +80,50 @@ class portfolio_plugin_googledocs extends portfolio_plugin_push_base {
return;
}
- if(!array_key_exists('token', $params)){
- throw new portfolio_plugin_exception('noauthtoken', 'portfolio_googledocs');
+ $this->initialize_oauth();
+ if ($this->googleoauth->is_logged_in()) {
+ return false;
+ } else {
+ return $this->googleoauth->get_login_url();
}
-
- // we now have our auth token, get a session token..
- $gauth = new google_authsub(false, $params['token']);
- $this->sessiontoken = $gauth->get_sessiontoken();
-
- google_docs::set_sesskey($this->sessiontoken, $this->get('user')->id);
}
public static function allows_multiple_instances() {
return false;
}
-}
-/**
- * Registers to the user_deleted event to revoke any
- * subauth tokens we have from them
- *
- * @param $user user object
- * @return boolean true in all cases as its only minor cleanup
- */
-function portfolio_googledocs_user_deleted($user){
- // it is only by luck that the user prefstill exists now?
- // We probably need a pre-delete event?
- if($sesskey = google_docs::get_sesskey($user->id)){
- try{
- $gauth = new google_authsub($sesskey);
-
- $gauth->revoke_session_token();
- }catch(Exception $e){
- // we don't care that much about success- just being good
- // google api citzens
- return true;
- }
+ public static function has_admin_config() {
+ return true;
}
- return true;
+ public static function get_allowed_config() {
+ return array('clientid', 'secret');
+ }
+
+ public function admin_config_form(&$mform) {
+ $a = new stdClass;
+ $a->docsurl = get_docs_url('Google_OAuth2_Setup');
+ $a->callbackurl = google_oauth::callback_url()->out(false);
+
+ $mform->addElement('static', null, '', get_string('oauthinfo', 'portfolio_googledocs', $a));
+
+ $mform->addElement('text', 'clientid', get_string('clientid', 'portfolio_googledocs'));
+ $mform->addElement('text', 'secret', get_string('secret', 'portfolio_googledocs'));
+
+ $strrequired = get_string('required');
+ $mform->addRule('clientid', $strrequired, 'required', null, 'client');
+ $mform->addRule('secret', $strrequired, 'required', null, 'client');
+ }
+
+ private function initialize_oauth() {
+ $returnurl = new moodle_url('/portfolio/add.php');
+ $returnurl->param('postcontrol', 1);
+ $returnurl->param('id', $this->exporter->get('id'));
+ $returnurl->param('sesskey', sesskey());
+
+ $clientid = $this->get_config('clientid');
+ $secret = $this->get_config('secret');
+
+ $this->googleoauth = new google_oauth($clientid, $secret, $returnurl->out(false), google_docs::REALM);
+ }
}
diff --git a/portfolio/googledocs/version.php b/portfolio/googledocs/version.php
index 20446664e67..a64c628b0b5 100644
--- a/portfolio/googledocs/version.php
+++ b/portfolio/googledocs/version.php
@@ -24,7 +24,7 @@
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2011112900; // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires = 2011112900; // Requires this Moodle version
-$plugin->component = 'portfolio_googledocs'; // Full name of the plugin (used for diagnostics)
+$plugin->version = 2012051400; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires = 2012051100; // Requires this Moodle version.
+$plugin->component = 'portfolio_googledocs'; // Full name of the plugin (used for diagnostics).
$plugin->cron = 0;
diff --git a/portfolio/picasa/lang/en/portfolio_picasa.php b/portfolio/picasa/lang/en/portfolio_picasa.php
index fec154b9391..10c12e66152 100644
--- a/portfolio/picasa/lang/en/portfolio_picasa.php
+++ b/portfolio/picasa/lang/en/portfolio_picasa.php
@@ -1,5 +1,4 @@
To use the Picasa portfolio you must be registered with Google. Instructions for registing your installation with Google are described in Moodle Docs. The redirect url should be set to:{$a->callbackurl}
';
$string['noauthtoken'] = 'An authentication token has not been recieved from google. Please ensure you are allowing moodle to access your google account';
$string['pluginname'] = 'Picasa';
$string['sendfailed'] = 'The file {$a} failed to transfer to picasa';
+$string['secret'] = 'Secret';
diff --git a/portfolio/picasa/lib.php b/portfolio/picasa/lib.php
index a9ba23fd886..6d21336214b 100644
--- a/portfolio/picasa/lib.php
+++ b/portfolio/picasa/lib.php
@@ -1,4 +1,19 @@
.
+
/**
* Picasa Portfolio Plugin
*
@@ -9,7 +24,7 @@ require_once($CFG->libdir.'/portfolio/plugin.php');
require_once($CFG->libdir.'/googleapi.php');
class portfolio_plugin_picasa extends portfolio_plugin_push_base {
- private $sessionkey;
+ private $googleoauth = null;
public function supported_formats() {
return array(PORTFOLIO_FORMAT_IMAGE, PORTFOLIO_FORMAT_VIDEO);
@@ -20,11 +35,11 @@ class portfolio_plugin_picasa extends portfolio_plugin_push_base {
}
public function prepare_package() {
- // we send the files as they are, no prep required
+ // We send the files as they are, no prep required.
return true;
}
- public function get_interactive_continue_url(){
+ public function get_interactive_continue_url() {
return 'http://picasaweb.google.com/';
}
@@ -33,40 +48,31 @@ class portfolio_plugin_picasa extends portfolio_plugin_push_base {
}
public function send_package() {
- if(!$this->sessionkey){
+ if (!$this->googleoauth) {
throw new portfolio_plugin_exception('noauthtoken', 'portfolio_picasa');
}
- $picasa = new google_picasa(new google_authsub($this->sessionkey));
-
+ $picasa = new google_picasa($this->googleoauth);
foreach ($this->exporter->get_tempfiles() as $file) {
- if(!$picasa->send_file($file)){
+ if (!$picasa->send_file($file)) {
throw new portfolio_plugin_exception('sendfailed', 'portfolio_picasa', $file->get_filename());
}
}
}
public function steal_control($stage) {
- global $CFG;
if ($stage != PORTFOLIO_STAGE_CONFIG) {
return false;
}
- $sesskey = google_picasa::get_sesskey($this->get('user')->id);
+ $this->initialize_oauth();
- if($sesskey){
- try{
- $gauth = new google_authsub($sesskey);
- $this->sessionkey = $sesskey;
- return false;
- }catch(Exception $e){
- // sesskey is not valid, delete store and re-auth
- google_picasa::delete_sesskey($this->get('user')->id);
- }
+ if ($this->googleoauth->is_logged_in()) {
+ return false;
+ } else {
+ return $this->googleoauth->get_login_url();
}
-
- return google_authsub::login_url($CFG->wwwroot.'/portfolio/add.php?postcontrol=1&id=' . $this->exporter->get('id') . '&sesskey=' . sesskey(), google_picasa::REALM);
}
public function post_control($stage, $params) {
@@ -74,44 +80,50 @@ class portfolio_plugin_picasa extends portfolio_plugin_push_base {
return;
}
- if(!array_key_exists('token', $params)){
- throw new portfolio_plugin_exception('noauthtoken', 'portfolio_picasa');
+ $this->initialize_oauth();
+ if ($this->googleoauth->is_logged_in()) {
+ return false;
+ } else {
+ return $this->googleoauth->get_login_url();
}
+ }
- // we now have our auth token, get a session token..
- $gauth = new google_authsub(false, $params['token']);
-
- $this->sessionkey = $gauth->get_sessiontoken();
-
- google_picasa::set_sesskey($this->sessionkey, $this->get('user')->id);
+ public static function has_admin_config() {
+ return true;
}
public static function allows_multiple_instances() {
return false;
}
-}
-/**
- * Registers to the user_deleted event to revoke any
- * subauth tokens we have from them
- *
- * @param $user user object
- * @return boolean true in all cases as its only minor cleanup
- */
-function portfolio_picasa_user_deleted($user){
- // it is only by luck that the user prefstill exists now?
- // We probably need a pre-delete event?
- if($sesskey = google_picasa::get_sesskey($user->id)){
- try{
- $gauth = new google_authsub($sesskey);
-
- $gauth->revoke_session_token();
- }catch(Exception $e){
- // we don't care that much about success- just being good
- // google api citzens
- return true;
- }
+ public static function get_allowed_config() {
+ return array('clientid', 'secret');
}
- return true;
+ public function admin_config_form(&$mform) {
+ $a = new stdClass;
+ $a->docsurl = get_docs_url('Google_OAuth2_Setup');
+ $a->callbackurl = google_oauth::callback_url()->out(false);
+
+ $mform->addElement('static', null, '', get_string('oauthinfo', 'portfolio_picasa', $a));
+
+ $mform->addElement('text', 'clientid', get_string('clientid', 'portfolio_picasa'));
+ $mform->addElement('text', 'secret', get_string('secret', 'portfolio_picasa'));
+
+ $strrequired = get_string('required');
+ $mform->addRule('clientid', $strrequired, 'required', null, 'client');
+ $mform->addRule('secret', $strrequired, 'required', null, 'client');
+ }
+
+ private function initialize_oauth() {
+ $returnurl = new moodle_url('/portfolio/add.php');
+ $returnurl->param('postcontrol', 1);
+ $returnurl->param('id', $this->exporter->get('id'));
+ $returnurl->param('sesskey', sesskey());
+
+ $clientid = $this->get_config('clientid');
+ $secret = $this->get_config('secret');
+
+ $this->googleoauth = new google_oauth($clientid, $secret, $returnurl->out(false), google_picasa::REALM);
+ }
}
diff --git a/portfolio/picasa/version.php b/portfolio/picasa/version.php
index 7906a251af3..113c9cf9e0d 100644
--- a/portfolio/picasa/version.php
+++ b/portfolio/picasa/version.php
@@ -24,7 +24,7 @@
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2011112900; // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires = 2011112900; // Requires this Moodle version
-$plugin->component = 'portfolio_picasa'; // Full name of the plugin (used for diagnostics)
+$plugin->version = 2012051400; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires = 2012051100; // Requires this Moodle version.
+$plugin->component = 'portfolio_picasa'; // Full name of the plugin (used for diagnostics).
$plugin->cron = 0;
diff --git a/portfolio/picasa/db/events.php b/repository/googledocs/db/upgrade.php
similarity index 58%
rename from portfolio/picasa/db/events.php
rename to repository/googledocs/db/upgrade.php
index 09ef7cca20c..76876a19ba2 100644
--- a/portfolio/picasa/db/events.php
+++ b/repository/googledocs/db/upgrade.php
@@ -15,19 +15,19 @@
// along with Moodle. If not, see .
/**
- * Add event handlers for the picasa portfolio.
- *
- * @package portfolio_picasa
- * @category event
- * @copyright 2009 Penny Leach
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @param int $oldversion the version we are upgrading from
+ * @return bool result
*/
+function xmldb_repository_googledocs_upgrade($oldversion) {
+ global $CFG, $DB;
-$handlers = array (
- 'user_deleted' => array (
- 'handlerfile' => '/portfolio/picasa/lib.php',
- 'handlerfunction' => 'portfolio_picasa_user_deleted',
- 'schedule' => 'cron',
- 'internal' => 0,
- ),
-);
\ No newline at end of file
+ $dbman = $DB->get_manager();
+
+ if ($oldversion < 2012051400) {
+ // Delete old user preferences containing authsub tokens.
+ $DB->delete_records('user_preferences', array('name' => 'google_authsub_sesskey'));
+ upgrade_plugin_savepoint(true, 2012051400, 'repository', 'googledocs');
+ }
+
+ return true;
+}
diff --git a/repository/googledocs/lang/en/repository_googledocs.php b/repository/googledocs/lang/en/repository_googledocs.php
index 38f1436b27a..8e8cf8034e1 100644
--- a/repository/googledocs/lang/en/repository_googledocs.php
+++ b/repository/googledocs/lang/en/repository_googledocs.php
@@ -1,5 +1,4 @@
To use the Google Docs repository you must be registered with Google. Instructions for registing your installation with Google are described in Moodle Docs. The redirect url should be set to:{$a->callbackurl}
';
$string['pluginname'] = 'Google Docs';
-$string['configplugin'] = 'Configurate Google Docs plugin';
+$string['secret'] = 'Secret';
+
diff --git a/repository/googledocs/lib.php b/repository/googledocs/lib.php
index 36648bdb81e..6ccb33bc436 100644
--- a/repository/googledocs/lib.php
+++ b/repository/googledocs/lib.php
@@ -34,55 +34,40 @@ require_once($CFG->libdir.'/googleapi.php');
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class repository_googledocs extends repository {
- private $subauthtoken = '';
+ private $googleoauth = null;
public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) {
- global $USER;
parent::__construct($repositoryid, $context, $options);
- // TODO: I wish there was somewhere we could explicitly put this outside of constructor..
- $googletoken = optional_param('token', false, PARAM_RAW);
- if($googletoken){
- $gauth = new google_authsub(false, $googletoken); // will throw exception if fails
- google_docs::set_sesskey($gauth->get_sessiontoken(), $USER->id);
- }
+ $returnurl = new moodle_url('/repository/repository_callback.php',
+ array('callback' => 'yes', 'repo_id' =>$this->id));
+
+ $clientid = get_config('googledocs', 'clientid');
+ $secret = get_config('googledocs', 'secret');
+ $this->googleoauth = new google_oauth($clientid, $secret, $returnurl->out(false), google_docs::REALM);
+
$this->check_login();
}
public function check_login() {
- global $USER;
-
- $sesskey = google_docs::get_sesskey($USER->id);
-
- if($sesskey){
- try{
- $gauth = new google_authsub($sesskey);
- $this->subauthtoken = $sesskey;
- return true;
- }catch(Exception $e){
- // sesskey is not valid, delete store and re-auth
- google_docs::delete_sesskey($USER->id);
- }
- }
-
- return false;
+ return $this->googleoauth->is_logged_in();
}
- public function print_login($ajax = true){
- global $CFG;
- if($ajax){
- $ret = array();
- $popup_btn = new stdClass();
- $popup_btn->type = 'popup';
- $returnurl = $CFG->wwwroot.'/repository/repository_callback.php?callback=yes&repo_id='.$this->id;
- $popup_btn->url = google_authsub::login_url($returnurl, google_docs::REALM);
- $ret['login'] = array($popup_btn);
- return $ret;
+ public function print_login() {
+ $url = $this->googleoauth->get_login_url();
+
+ if ($this->options['ajax']) {
+ $popup = new stdClass();
+ $popup->type = 'popup';
+ $popup->url = $url->out(false);
+ return array('login' => array($popup));
+ } else {
+ echo ''.get_string('login', 'repository').'';
}
}
public function get_listing($path='', $page = '') {
- $gdocs = new google_docs(new google_authsub($this->subauthtoken));
+ $gdocs = new google_docs($this->googleoauth);
$ret = array();
$ret['dynload'] = true;
@@ -91,7 +76,7 @@ class repository_googledocs extends repository {
}
public function search($search_text, $page = 0) {
- $gdocs = new google_docs(new google_authsub($this->subauthtoken));
+ $gdocs = new google_docs($this->googleoauth);
$ret = array();
$ret['dynload'] = true;
@@ -99,37 +84,44 @@ class repository_googledocs extends repository {
return $ret;
}
- public function logout(){
- global $USER;
-
- $token = google_docs::get_sesskey($USER->id);
-
- $gauth = new google_authsub($token);
- // revoke token from google
- $gauth->revoke_session_token();
-
- google_docs::delete_sesskey($USER->id);
- $this->subauthtoken = '';
-
+ public function logout() {
+ $this->googleoauth->log_out();
return parent::logout();
}
public function get_file($url, $file = '') {
- global $CFG;
+ $gdocs = new google_docs($this->googleoauth);
+
$path = $this->prepare_file($file);
-
- $fp = fopen($path, 'w');
- $gdocs = new google_docs(new google_authsub($this->subauthtoken));
- $gdocs->download_file($url, $fp);
-
- return array('path'=>$path, 'url'=>$url);
+ return $gdocs->download_file($url, $path);
}
public function supported_filetypes() {
- return array('document');
+ return '*';
}
public function supported_returntypes() {
return FILE_INTERNAL;
}
+
+ public static function get_type_option_names() {
+ return array('clientid', 'secret', 'pluginname');
+ }
+
+ public static function type_config_form($mform, $classname = 'repository') {
+
+ $a = new stdClass;
+ $a->docsurl = get_docs_url('Google_OAuth2_Setup');
+ $a->callbackurl = google_oauth::callback_url()->out(false);
+
+ $mform->addElement('static', null, '', get_string('oauthinfo', 'repository_googledocs', $a));
+
+ parent::type_config_form($mform);
+ $mform->addElement('text', 'clientid', get_string('clientid', 'repository_googledocs'));
+ $mform->addElement('text', 'secret', get_string('secret', 'repository_googledocs'));
+
+ $strrequired = get_string('required');
+ $mform->addRule('clientid', $strrequired, 'required', null, 'client');
+ $mform->addRule('secret', $strrequired, 'required', null, 'client');
+ }
}
-//Icon from: http://www.iconspedia.com/icon/google-2706.html
+// Icon from: http://www.iconspedia.com/icon/google-2706.html.
diff --git a/repository/googledocs/version.php b/repository/googledocs/version.php
index 79c6db7ff39..7269aa52195 100644
--- a/repository/googledocs/version.php
+++ b/repository/googledocs/version.php
@@ -25,6 +25,6 @@
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2011112900; // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires = 2011112900; // Requires this Moodle version
-$plugin->component = 'repository_googledocs'; // Full name of the plugin (used for diagnostics)
+$plugin->version = 2012051400; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires = 2012051100; // Requires this Moodle version.
+$plugin->component = 'repository_googledocs'; // Full name of the plugin (used for diagnostics).
diff --git a/portfolio/googledocs/db/events.php b/repository/picasa/db/upgrade.php
similarity index 58%
rename from portfolio/googledocs/db/events.php
rename to repository/picasa/db/upgrade.php
index b0d3d0c702f..545ce3b4fa5 100644
--- a/portfolio/googledocs/db/events.php
+++ b/repository/picasa/db/upgrade.php
@@ -15,21 +15,19 @@
// along with Moodle. If not, see .
/**
- * Add event handlers for the googledocs portfolio.
- *
- * @package portfolio_googledocs
- * @category event
- * @copyright 2009 Penny Leach
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @param int $oldversion the version we are upgrading from
+ * @return bool result
*/
+function xmldb_repository_picasa_upgrade($oldversion) {
+ global $CFG, $DB;
-$handlers = array (
- 'user_deleted' => array (
- 'handlerfile' => '/portfolio/googledocs/lib.php',
- 'handlerfunction' => 'portfolio_googledocs_user_deleted',
- 'schedule' => 'cron',
- 'internal' => 0,
- ),
-);
+ $dbman = $DB->get_manager();
+ if ($oldversion < 2012051400) {
+ // Delete old user preferences storing authsub tokens.
+ $DB->delete_records('user_preferences', array('name' => 'google_authsub_sesskey_picasa'));
+ upgrade_plugin_savepoint(true, 2012051400, 'repository', 'picasa');
+ }
+ return true;
+}
diff --git a/repository/picasa/lang/en/repository_picasa.php b/repository/picasa/lang/en/repository_picasa.php
index 23d9dbe66bb..3c03022c12b 100644
--- a/repository/picasa/lang/en/repository_picasa.php
+++ b/repository/picasa/lang/en/repository_picasa.php
@@ -1,5 +1,4 @@
To use the Picasa repository you must be registered with Google. Instructions for registing your installation with Google are described in Moodle Docs. The redirect url should be set to:{$a->callbackurl}
';
$string['picasa:view'] = 'View picasa repository';
$string['pluginname'] = 'Picasa web album';
-$string['configplugin'] = 'Picasa repository configuration';
+$string['secret'] = 'Secret';
diff --git a/repository/picasa/lib.php b/repository/picasa/lib.php
index 6a83ca08238..902238025fa 100644
--- a/repository/picasa/lib.php
+++ b/repository/picasa/lib.php
@@ -36,58 +36,40 @@ require_once($CFG->libdir.'/googleapi.php');
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class repository_picasa extends repository {
- private $subauthtoken = '';
+ private $googleoauth = null;
public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) {
- global $USER;
parent::__construct($repositoryid, $context, $options);
- // TODO: I wish there was somewhere we could explicitly put this outside of constructor..
- $googletoken = optional_param('token', false, PARAM_RAW);
- if($googletoken){
- $gauth = new google_authsub(false, $googletoken); // will throw exception if fails
- google_picasa::set_sesskey($gauth->get_sessiontoken(), $USER->id);
- }
+ $returnurl = new moodle_url('/repository/repository_callback.php',
+ array('callback' => 'yes', 'repo_id' =>$this->id));
+
+ $clientid = get_config('picasa', 'clientid');
+ $secret = get_config('picasa', 'secret');
+ $this->googleoauth = new google_oauth($clientid, $secret, $returnurl->out(false), google_picasa::REALM);
+
$this->check_login();
}
public function check_login() {
- global $USER;
-
- $sesskey = google_picasa::get_sesskey($USER->id);
-
- if($sesskey){
- try{
- $gauth = new google_authsub($sesskey);
- $this->subauthtoken = $sesskey;
- return true;
- }catch(Exception $e){
- // sesskey is not valid, delete store and re-auth
- google_picasa::delete_sesskey($USER->id);
- }
- }
-
- return false;
+ return $this->googleoauth->is_logged_in();
}
- public function print_login(){
- global $CFG;
- $returnurl = $CFG->wwwroot.'/repository/repository_callback.php?callback=yes&repo_id='.$this->id;
- $authurl = google_authsub::login_url($returnurl, google_picasa::REALM);
- if($this->options['ajax']){
- $ret = array();
- $popup_btn = new stdClass();
- $popup_btn->type = 'popup';
- $popup_btn->url = $authurl;
- $ret['login'] = array($popup_btn);
- return $ret;
+ public function print_login() {
+ $url = $this->googleoauth->get_login_url();
+
+ if ($this->options['ajax']) {
+ $popup = new stdClass();
+ $popup->type = 'popup';
+ $popup->url = $url->out(false);
+ return array('login' => array($popup));
} else {
- echo 'Login';
+ echo ''.get_string('login', 'repository').'';
}
}
public function get_listing($path='', $page = '') {
- $picasa = new google_picasa(new google_authsub($this->subauthtoken));
+ $picasa = new google_picasa($this->googleoauth);
$ret = array();
$ret['dynload'] = true;
@@ -101,7 +83,7 @@ class repository_picasa extends repository {
}
public function search($search_text, $page = 0) {
- $picasa = new google_picasa(new google_authsub($this->subauthtoken));
+ $picasa = new google_picasa($this->googleoauth);
$ret = array();
$ret['manage'] = google_picasa::MANAGE_URL;
@@ -109,22 +91,12 @@ class repository_picasa extends repository {
return $ret;
}
- public function logout(){
- global $USER;
-
- $token = google_picasa::get_sesskey($USER->id);
-
- $gauth = new google_authsub($token);
- // revoke token from google
- $gauth->revoke_session_token();
-
- google_picasa::delete_sesskey($USER->id);
- $this->subauthtoken = '';
-
+ public function logout() {
+ $this->googleoauth->log_out();
return parent::logout();
}
- public function get_name(){
+ public function get_name() {
return get_string('pluginname', 'repository_picasa');
}
public function supported_filetypes() {
@@ -133,7 +105,27 @@ class repository_picasa extends repository {
public function supported_returntypes() {
return (FILE_INTERNAL | FILE_EXTERNAL);
}
+
+ public static function get_type_option_names() {
+ return array('clientid', 'secret', 'pluginname');
+ }
+
+ public static function type_config_form($mform, $classname = 'repository') {
+ $a = new stdClass;
+ $a->docsurl = get_docs_url('Google_OAuth2_Setup');
+ $a->callbackurl = google_oauth::callback_url()->out(false);
+
+ $mform->addElement('static', null, '', get_string('oauthinfo', 'repository_picasa', $a));
+
+ parent::type_config_form($mform);
+ $mform->addElement('text', 'clientid', get_string('clientid', 'repository_picasa'));
+ $mform->addElement('text', 'secret', get_string('secret', 'repository_picasa'));
+
+ $strrequired = get_string('required');
+ $mform->addRule('clientid', $strrequired, 'required', null, 'client');
+ $mform->addRule('secret', $strrequired, 'required', null, 'client');
+ }
}
// Icon for this plugin retrieved from http://www.iconspedia.com/icon/picasa-2711.html
-// Where the license is said documented to be Free
+// Where the license is said documented to be Free.
diff --git a/repository/picasa/version.php b/repository/picasa/version.php
index 5ee9d18b00a..471007a4cac 100644
--- a/repository/picasa/version.php
+++ b/repository/picasa/version.php
@@ -26,6 +26,6 @@
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2011112900; // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires = 2011112900; // Requires this Moodle version
-$plugin->component = 'repository_picasa'; // Full name of the plugin (used for diagnostics)
+$plugin->version = 2012051400; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires = 2012051100; // Requires this Moodle version.
+$plugin->component = 'repository_picasa'; // Full name of the plugin (used for diagnostics).
From ce30ff5df04b5c4619eede6f43f6d2d3131cb2cb Mon Sep 17 00:00:00 2001
From: Dan Poltawski
Date: Wed, 30 May 2012 23:56:07 +0800
Subject: [PATCH 5/6] MDL-29857 google apis: OAuth 2.0 repository plugins
upgrade
We are disabling the plugins on upgrade and emailing admins
about this if they have a plugin configured.
This is required because OAuth 2 credentials are now required
in the plugin configuration.
NOTE: These strings are temporary and need to be improved.
---
repository/googledocs/db/upgrade.php | 37 +++++++++++++++++++
.../lang/en/repository_googledocs.php | 3 ++
repository/googledocs/version.php | 2 +-
repository/picasa/db/upgrade.php | 37 +++++++++++++++++++
.../picasa/lang/en/repository_picasa.php | 3 ++
repository/picasa/version.php | 2 +-
6 files changed, 82 insertions(+), 2 deletions(-)
diff --git a/repository/googledocs/db/upgrade.php b/repository/googledocs/db/upgrade.php
index 76876a19ba2..893ed39dced 100644
--- a/repository/googledocs/db/upgrade.php
+++ b/repository/googledocs/db/upgrade.php
@@ -29,5 +29,42 @@ function xmldb_repository_googledocs_upgrade($oldversion) {
upgrade_plugin_savepoint(true, 2012051400, 'repository', 'googledocs');
}
+ if ($oldversion < 2012053000) {
+ require_once($CFG->dirroot.'/repository/lib.php');
+ $existing = $DB->get_record('repository', array('type' => 'googledocs'), '*', IGNORE_MULTIPLE);
+
+ if ($existing) {
+ $googledocsplugin = new repository_type('googledocs', array(), true);
+ $googledocsplugin->delete();
+ repository_googledocs_admin_upgrade_notification();
+ }
+
+ upgrade_plugin_savepoint(true, 2012053000, 'repository', 'googledocs');
+ }
+
return true;
}
+
+function repository_googledocs_admin_upgrade_notification() {
+ $admins = get_admins();
+
+ if (empty($admins)) {
+ return;
+ }
+ $mainadmin = reset($admins);
+
+ foreach ($admins as $admin) {
+ $message = new stdClass();
+ $message->component = 'moodle';
+ $message->name = 'notices';
+ $message->userfrom = $mainadmin;
+ $message->userto = $admin;
+ $message->smallmessage = get_string('oauth2upgrade_message_small', 'repository_googledocs');
+ $message->subject = get_string('oauth2upgrade_message_subject', 'repository_googledocs');
+ $message->fullmessage = get_string('oauth2upgrade_message_content', 'repository_googledocs');
+ $message->fullmessagehtml = get_string('oauth2upgrade_message_content', 'repository_googledocs');
+ $message->fullmessageformat = FORMAT_PLAIN;
+ $message->notification = 1;
+ message_send($message);
+ }
+}
diff --git a/repository/googledocs/lang/en/repository_googledocs.php b/repository/googledocs/lang/en/repository_googledocs.php
index 8e8cf8034e1..4f7faa7b324 100644
--- a/repository/googledocs/lang/en/repository_googledocs.php
+++ b/repository/googledocs/lang/en/repository_googledocs.php
@@ -26,6 +26,9 @@ $string['clientid'] = 'Client ID';
$string['configplugin'] = 'Configure Google Docs plugin';
$string['googledocs:view'] = 'View google docs repository';
$string['oauthinfo'] = 'To use the Google Docs repository you must be registered with Google. Instructions for registing your installation with Google are described in Moodle Docs. The redirect url should be set to:
{$a->callbackurl}
';
+$string['oauth2upgrade_message_subject'] = 'Important information regarding Google Docs repository plugin';
+$string['oauth2upgrade_message_content'] = 'As part of the upgrade to Moodle 2.3, the Google Docs repository plugin has been disabled due to changes in Googles API. To re-enable your plugin, you must add and reconfigure configure oauth credentials of this plugin.';
+$string['oauth2upgrade_message_small'] = 'The Google Docs repository plugin has been disabled until configured with OAuth2';
$string['pluginname'] = 'Google Docs';
$string['secret'] = 'Secret';
diff --git a/repository/googledocs/version.php b/repository/googledocs/version.php
index 7269aa52195..2e03f6c9c43 100644
--- a/repository/googledocs/version.php
+++ b/repository/googledocs/version.php
@@ -25,6 +25,6 @@
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2012051400; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->version = 2012053000; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2012051100; // Requires this Moodle version.
$plugin->component = 'repository_googledocs'; // Full name of the plugin (used for diagnostics).
diff --git a/repository/picasa/db/upgrade.php b/repository/picasa/db/upgrade.php
index 545ce3b4fa5..082e5e3433f 100644
--- a/repository/picasa/db/upgrade.php
+++ b/repository/picasa/db/upgrade.php
@@ -29,5 +29,42 @@ function xmldb_repository_picasa_upgrade($oldversion) {
upgrade_plugin_savepoint(true, 2012051400, 'repository', 'picasa');
}
+ if ($oldversion < 2012053000) {
+ require_once($CFG->dirroot.'/repository/lib.php');
+ $existing = $DB->get_record('repository', array('type' => 'picasa'), '*', IGNORE_MULTIPLE);
+
+ if ($existing) {
+ $picasaplugin = new repository_type('picasa', array(), true);
+ $picasaplugin->delete();
+ repository_picasa_admin_upgrade_notification();
+ }
+
+ upgrade_plugin_savepoint(true, 2012053000, 'repository', 'picasa');
+ }
+
return true;
}
+
+function repository_picasa_admin_upgrade_notification() {
+ $admins = get_admins();
+
+ if (empty($admins)) {
+ return;
+ }
+ $mainadmin = reset($admins);
+
+ foreach ($admins as $admin) {
+ $message = new stdClass();
+ $message->component = 'moodle';
+ $message->name = 'notices';
+ $message->userfrom = $mainadmin;
+ $message->userto = $admin;
+ $message->smallmessage = get_string('oauth2upgrade_message_small', 'repository_picasa');
+ $message->subject = get_string('oauth2upgrade_message_subject', 'repository_picasa');
+ $message->fullmessage = get_string('oauth2upgrade_message_content', 'repository_picasa');
+ $message->fullmessagehtml = get_string('oauth2upgrade_message_content', 'repository_picasa');
+ $message->fullmessageformat = FORMAT_PLAIN;
+ $message->notification = 1;
+ message_send($message);
+ }
+}
diff --git a/repository/picasa/lang/en/repository_picasa.php b/repository/picasa/lang/en/repository_picasa.php
index 3c03022c12b..89d75a68079 100644
--- a/repository/picasa/lang/en/repository_picasa.php
+++ b/repository/picasa/lang/en/repository_picasa.php
@@ -25,6 +25,9 @@
$string['clientid'] = 'Client ID';
$string['configplugin'] = 'Picasa repository configuration';
$string['oauthinfo'] = 'To use the Picasa repository you must be registered with Google. Instructions for registing your installation with Google are described in Moodle Docs. The redirect url should be set to:
{$a->callbackurl}
';
+$string['oauth2upgrade_message_subject'] = 'Important information regarding Picasa repository plugin';
+$string['oauth2upgrade_message_content'] = 'As part of the upgrade to Moodle 2.3, the Picasa repository plugin has been disabled due to changes in Googles API. To re-enable your plugin, you must add and reconfigure configure oauth credentials of this plugin.';
+$string['oauth2upgrade_message_small'] = 'The Picasa repository plugin has been disabled until configured with OAuth2';
$string['picasa:view'] = 'View picasa repository';
$string['pluginname'] = 'Picasa web album';
$string['secret'] = 'Secret';
diff --git a/repository/picasa/version.php b/repository/picasa/version.php
index 471007a4cac..c6dc0fc84ff 100644
--- a/repository/picasa/version.php
+++ b/repository/picasa/version.php
@@ -26,6 +26,6 @@
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2012051400; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->version = 2012053000; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2012051100; // Requires this Moodle version.
$plugin->component = 'repository_picasa'; // Full name of the plugin (used for diagnostics).
From b7acfd645b4f71d3012e706f30dd4165c2b11e26 Mon Sep 17 00:00:00 2001
From: Dan Poltawski
Date: Tue, 29 May 2012 14:35:25 +0800
Subject: [PATCH 6/6] MDL-29857 google apis: OAuth 2.0 portfolio plugins
upgrade
We are disabling the plugins if not configured. As part of
this upgrade we will emailing admins about this change
if they have a plugin configured.
This is required because OAuth 2 credentials are now required
in the plugin configuration.
NOTE: These strings are temporary and need to be improved.
---
portfolio/googledocs/db/upgrade.php | 67 +++++++++++++++++++
.../lang/en/portfolio_googledocs.php | 7 +-
portfolio/googledocs/lib.php | 12 ++++
portfolio/googledocs/version.php | 2 +-
portfolio/picasa/db/upgrade.php | 67 +++++++++++++++++++
portfolio/picasa/lang/en/portfolio_picasa.php | 7 +-
portfolio/picasa/lib.php | 12 ++++
portfolio/picasa/version.php | 2 +-
8 files changed, 172 insertions(+), 4 deletions(-)
create mode 100644 portfolio/googledocs/db/upgrade.php
create mode 100644 portfolio/picasa/db/upgrade.php
diff --git a/portfolio/googledocs/db/upgrade.php b/portfolio/googledocs/db/upgrade.php
new file mode 100644
index 00000000000..dfdc1dca43a
--- /dev/null
+++ b/portfolio/googledocs/db/upgrade.php
@@ -0,0 +1,67 @@
+.
+
+/**
+ * @param int $oldversion the version we are upgrading from
+ * @return bool result
+ */
+function xmldb_portfolio_googledocs_upgrade($oldversion) {
+ global $CFG, $DB;
+
+ $dbman = $DB->get_manager();
+
+ if ($oldversion < 2012053000) {
+ // Delete old user preferences containing authsub tokens.
+ $DB->delete_records('user_preferences', array('name' => 'google_authsub_sesskey'));
+ upgrade_plugin_savepoint(true, 2012053000, 'portfolio', 'googledocs');
+ }
+
+ if ($oldversion < 2012053001) {
+ $existing = $DB->get_record('portfolio_instance', array('plugin' => 'googledocs'), '*', IGNORE_MULTIPLE);
+
+ if ($existing) {
+ portfolio_googledocs_admin_upgrade_notification();
+ }
+
+ upgrade_plugin_savepoint(true, 2012053001, 'portfolio', 'googledocs');
+ }
+
+ return true;
+}
+
+function portfolio_googledocs_admin_upgrade_notification() {
+ $admins = get_admins();
+
+ if (empty($admins)) {
+ return;
+ }
+ $mainadmin = reset($admins);
+
+ foreach ($admins as $admin) {
+ $message = new stdClass();
+ $message->component = 'moodle';
+ $message->name = 'notices';
+ $message->userfrom = $mainadmin;
+ $message->userto = $admin;
+ $message->smallmessage = get_string('oauth2upgrade_message_small', 'portfolio_googledocs');
+ $message->subject = get_string('oauth2upgrade_message_subject', 'portfolio_googledocs');
+ $message->fullmessage = get_string('oauth2upgrade_message_content', 'portfolio_googledocs');
+ $message->fullmessagehtml = get_string('oauth2upgrade_message_content', 'portfolio_googledocs');
+ $message->fullmessageformat = FORMAT_PLAIN;
+ $message->notification = 1;
+ message_send($message);
+ }
+}
diff --git a/portfolio/googledocs/lang/en/portfolio_googledocs.php b/portfolio/googledocs/lang/en/portfolio_googledocs.php
index 0fb864dac40..c52bba14df5 100644
--- a/portfolio/googledocs/lang/en/portfolio_googledocs.php
+++ b/portfolio/googledocs/lang/en/portfolio_googledocs.php
@@ -23,9 +23,14 @@
*/
$string['clientid'] = 'Client ID';
-$string['oauthinfo'] = 'To use the google docs portfolio you must be registered with Google. Instructions for registing your installation with Google are described in Moodle Docs. The redirect url should be set to:
{$a->callbackurl}
';
$string['noauthtoken'] = 'An authentication token has not been recieved from google. Please ensure you are allowing moodle to access your google account';
+$string['nooauthcredentials'] = 'OAuth credentials required.';
+$string['nooauthcredentials_help'] = 'To use the Google Docs portfolio plugin you must configure OAuth credentials in the portfolio settings.';
$string['nosessiontoken'] = 'A session token does not exist preventing export to google.';
+$string['oauthinfo'] = 'To use the google docs portfolio you must be registered with Google. Instructions for registing your installation with Google are described in Moodle Docs. The redirect url should be set to:
{$a->callbackurl}
';
+$string['oauth2upgrade_message_subject'] = 'Important information regarding Google Docs portfolio plugin';
+$string['oauth2upgrade_message_content'] = 'As part of the upgrade to Moodle 2.3, the Google Docs portfolio plugin has been disabled due to changes in Googles API. To re-enable your plugin, you must configure oauth credentials in this plugin.';
+$string['oauth2upgrade_message_small'] = 'The Google Docs portfolio plugin has been disabled until configured with OAuth2';
$string['pluginname'] = 'Google Docs';
$string['sendfailed'] = 'The file {$a} failed to transfer to google';
$string['secret'] = 'Secret';
diff --git a/portfolio/googledocs/lib.php b/portfolio/googledocs/lib.php
index c641f096df1..9820246f9db 100644
--- a/portfolio/googledocs/lib.php
+++ b/portfolio/googledocs/lib.php
@@ -126,4 +126,16 @@ class portfolio_plugin_googledocs extends portfolio_plugin_push_base {
$this->googleoauth = new google_oauth($clientid, $secret, $returnurl->out(false), google_docs::REALM);
}
+
+ public function instance_sanity_check() {
+ $clientid = $this->get_config('clientid');
+ $secret = $this->get_config('secret');
+
+ // If there is no oauth config (e.g. plugins upgraded from < 2.3 then
+ // there will be no config and this plugin should be disabled.
+ if (empty($clientid) or empty($secret)) {
+ return 'nooauthcredentials';
+ }
+ return 0;
+ }
}
diff --git a/portfolio/googledocs/version.php b/portfolio/googledocs/version.php
index a64c628b0b5..5cee5db320b 100644
--- a/portfolio/googledocs/version.php
+++ b/portfolio/googledocs/version.php
@@ -24,7 +24,7 @@
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2012051400; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->version = 2012053001; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2012051100; // Requires this Moodle version.
$plugin->component = 'portfolio_googledocs'; // Full name of the plugin (used for diagnostics).
$plugin->cron = 0;
diff --git a/portfolio/picasa/db/upgrade.php b/portfolio/picasa/db/upgrade.php
new file mode 100644
index 00000000000..e5d1cca6d1d
--- /dev/null
+++ b/portfolio/picasa/db/upgrade.php
@@ -0,0 +1,67 @@
+.
+
+/**
+ * @param int $oldversion the version we are upgrading from
+ * @return bool result
+ */
+function xmldb_portfolio_picasa_upgrade($oldversion) {
+ global $CFG, $DB;
+
+ $dbman = $DB->get_manager();
+
+ if ($oldversion < 2012053000) {
+ // Delete old user preferences containing authsub tokens.
+ $DB->delete_records('user_preferences', array('name' => 'google_authsub_sesskey_picasa'));
+ upgrade_plugin_savepoint(true, 2012053000, 'portfolio', 'picasa');
+ }
+
+ if ($oldversion < 2012053001) {
+ $existing = $DB->get_record('portfolio_instance', array('plugin' => 'picasa'), '*', IGNORE_MISSING);
+
+ if ($existing) {
+ portfolio_picasa_admin_upgrade_notification();
+ }
+
+ upgrade_plugin_savepoint(true, 2012053001, 'portfolio', 'picasa');
+ }
+
+ return true;
+}
+
+function portfolio_picasa_admin_upgrade_notification() {
+ $admins = get_admins();
+
+ if (empty($admins)) {
+ return;
+ }
+ $mainadmin = reset($admins);
+
+ foreach ($admins as $admin) {
+ $message = new stdClass();
+ $message->component = 'moodle';
+ $message->name = 'notices';
+ $message->userfrom = $mainadmin;
+ $message->userto = $admin;
+ $message->smallmessage = get_string('oauth2upgrade_message_small', 'portfolio_picasa');
+ $message->subject = get_string('oauth2upgrade_message_subject', 'portfolio_picasa');
+ $message->fullmessage = get_string('oauth2upgrade_message_content', 'portfolio_picasa');
+ $message->fullmessagehtml = get_string('oauth2upgrade_message_content', 'portfolio_picasa');
+ $message->fullmessageformat = FORMAT_PLAIN;
+ $message->notification = 1;
+ message_send($message);
+ }
+}
diff --git a/portfolio/picasa/lang/en/portfolio_picasa.php b/portfolio/picasa/lang/en/portfolio_picasa.php
index 10c12e66152..93781b6df96 100644
--- a/portfolio/picasa/lang/en/portfolio_picasa.php
+++ b/portfolio/picasa/lang/en/portfolio_picasa.php
@@ -23,8 +23,13 @@
*/
$string['clientid'] = 'Client ID';
-$string['oauthinfo'] = 'To use the Picasa portfolio you must be registered with Google. Instructions for registing your installation with Google are described in Moodle Docs. The redirect url should be set to:
{$a->callbackurl}
';
$string['noauthtoken'] = 'An authentication token has not been recieved from google. Please ensure you are allowing moodle to access your google account';
+$string['nooauthcredentials'] = 'OAuth credentials required.';
+$string['nooauthcredentials_help'] = 'To use the Picasa portfolio plugin you must configure OAuth credentials in the portfolio settings.';
+$string['oauthinfo'] = 'To use the Picasa portfolio you must be registered with Google. Instructions for registing your installation with Google are described in Moodle Docs. The redirect url should be set to:
{$a->callbackurl}
';
+$string['oauth2upgrade_message_subject'] = 'Important information regarding Picasa portfolio plugin';
+$string['oauth2upgrade_message_content'] = 'As part of the upgrade to Moodle 2.3, the Picasa portfolio plugin has been disabled due to changes in Googles API. To re-enable your plugin, you must configure oauth credentials in this plugin.';
+$string['oauth2upgrade_message_small'] = 'The Picasa portfolio plugin has been disabled until configured with OAuth2';
$string['pluginname'] = 'Picasa';
$string['sendfailed'] = 'The file {$a} failed to transfer to picasa';
$string['secret'] = 'Secret';
diff --git a/portfolio/picasa/lib.php b/portfolio/picasa/lib.php
index 6d21336214b..d637b54edca 100644
--- a/portfolio/picasa/lib.php
+++ b/portfolio/picasa/lib.php
@@ -126,4 +126,16 @@ class portfolio_plugin_picasa extends portfolio_plugin_push_base {
$this->googleoauth = new google_oauth($clientid, $secret, $returnurl->out(false), google_picasa::REALM);
}
+
+ public function instance_sanity_check() {
+ $clientid = $this->get_config('clientid');
+ $secret = $this->get_config('secret');
+
+ // If there is no oauth config (e.g. plugins upgraded from < 2.3 then
+ // there will be no config and this plugin should be disabled.
+ if (empty($clientid) or empty($secret)) {
+ return 'nooauthcredentials';
+ }
+ return 0;
+ }
}
diff --git a/portfolio/picasa/version.php b/portfolio/picasa/version.php
index 113c9cf9e0d..b56c5e65b00 100644
--- a/portfolio/picasa/version.php
+++ b/portfolio/picasa/version.php
@@ -24,7 +24,7 @@
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2012051400; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->version = 2012053001; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2012051100; // Requires this Moodle version.
$plugin->component = 'portfolio_picasa'; // Full name of the plugin (used for diagnostics).
$plugin->cron = 0;