Skip to content

Commit

Permalink
MDL-21579 "Implement session token for embedded application" implemen…
Browse files Browse the repository at this point in the history
…ted a second type of session token linked to a session for use in applications embedded in web pages.
  • Loading branch information
jamiepratt committed Apr 28, 2010
1 parent aa6fae5 commit 2d0acbd
Show file tree
Hide file tree
Showing 18 changed files with 177 additions and 93 deletions.
6 changes: 6 additions & 0 deletions admin/cron.php
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,12 @@
$fs = get_file_storage();
$fs->cron();

//cleanup old session linked tokens
//deletes the session linked tokens that are over a day old.
mtrace("Deleting session linked tokens more than one day old...", '');
$DB->delete_records_select('external_tokens', 'lastaccess < {onedayago} AND tokentype = {tokentype}',
array('onedayago' => time() - DAYSECS, 'tokentype' => EXTERNAL_TOKEN_EMBEDDED));

// run any customized cronjobs, if any
if ($locals = get_plugin_list('local')) {
mtrace('Processing customized cron scripts ...', '');
Expand Down
2 changes: 1 addition & 1 deletion lang/en/error.php
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@
$string['targetdatabasenotempty'] = 'The target database is not empty. Transfer aborted for safety reasons.';
$string['themenotinstall'] = 'This theme is not installed!';
$string['TODO'] = 'TODO';
$string['tokenalreadyexist'] = 'The generated token already exists, try again.';
$string['tokengenerationfailed'] = 'Cannot generate a new token.';
$string['transactionvoid'] = 'Transaction cannot be voided because it has already been voided';
$string['unenrolerror'] = 'An error occurred while trying to unenrol that person';
$string['unicodeupgradeerror'] = 'Sorry, but your database is not already in Unicode, and this version of Moodle is not able to migrate your database to Unicode. Please upgrade to Moodle 1.7.x first and perform the Unicode migration from the Admin page. After that is done you should be able to migrate to Moodle {$a}';
Expand Down
1 change: 1 addition & 0 deletions lang/en/webservice.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
$string['invalidiptoken'] = 'Invalid token - your IP is not supported';
$string['invalidtimedtoken'] = 'Invalid token - token expired';
$string['invalidtoken'] = 'Invalid token - token not found';
$string['invalidtokensession'] = 'Invalid session based token - session not found or expired';
$string['iprestriction'] = 'IP restriction';
$string['key'] = 'Key';
$string['keyshelp'] = 'The keys are used to access your Moodle account from external applications.';
Expand Down
17 changes: 17 additions & 0 deletions lib/externallib.php
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,9 @@ function external_generate_token($tokentype, $serviceorid, $userid, $contextorid
}
$newtoken->tokentype = $tokentype;
$newtoken->userid = $userid;
if ($tokentype == EXTERNAL_TOKEN_EMBEDDED){
$newtoken->sid = session_id();
}

$newtoken->contextid = $context->id;
$newtoken->creatorid = $USER->id;
Expand All @@ -463,4 +466,18 @@ function external_generate_token($tokentype, $serviceorid, $userid, $contextorid
}
$DB->insert_record('external_tokens', $newtoken);
return $newtoken->token;
}
/**
* Create and return a session linked token. Token to be used for html embedded client apps that want to communicate
* with the Moodle server through web services. The token is linked to the current session for the current page request.
* It is expected this will be called in the script generating the html page that is embedding the client app and that the
* returned token will be somehow passed into the client app being embedded in the page.
* @param string $servicename name of the web service. Service name as defined in db/services.php
* @param int $context context within which the web service can operate.
* @return int returns token id.
*/
function external_create_service_token($servicename, $context){
global $USER, $DB;
$service = $DB->get_record('external_services', array('name'=>$servicename), '*', MUST_EXIST);
return external_generate_token(EXTERNAL_TOKEN_EMBEDDED, $service, $USER->id, $context, 0);
}
38 changes: 36 additions & 2 deletions lib/sessionlib.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ public function terminate_current();
* @return void
*/
public function write_close();

/**
* Check for existing session with id $sid
* @param unknown_type $sid
* @return boolean true if session found.
*/
public function session_exists($sid);
}

/**
Expand Down Expand Up @@ -145,8 +152,10 @@ public function __construct() {
* Terminates active moodle session
*/
public function terminate_current() {
global $CFG, $SESSION, $USER;
global $CFG, $SESSION, $USER, $DB;

$DB->delete_records('external_tokens', array('sid'=>session_id(), 'tokentype'=>EXTERNAL_TOKEN_EMBEDDED));

if (NO_MOODLE_COOKIES) {
return;
}
Expand Down Expand Up @@ -349,6 +358,18 @@ protected function init_session_storage() {
}
ini_set('session.save_path', $CFG->dataroot .'/sessions');
}
/**
* Check for existing session with id $sid
* @param unknown_type $sid
* @return boolean true if session found.
*/
public function session_exists($sid){
$sid = clean_param($sid, PARAM_FILE);
$sessionfile = clean_param("$CFG->dataroot/sessions/sess_$sid", PARAM_FILE);
return file_exists($sessionfile);
}


}

/**
Expand Down Expand Up @@ -376,7 +397,20 @@ public function __construct() {
}
}
}


public function session_exists($sid){
global $CFG;
try {
$sql = "SELECT * FROM {sessions} WHERE timemodified < ? AND sid=? AND state=?";
$params = array(time() + $CFG->sessiontimeout, $sid, 0);

return $this->database->record_exists_sql($sql, $params);
} catch (dml_exception $ex) {
error_log('Error checking existance of database session');
return false;
}
}

protected function init_session_storage() {
global $CFG;

Expand Down
68 changes: 35 additions & 33 deletions webservice/amf/locallib.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,26 +47,28 @@ function __construct($debuginfo=null) {
class webservice_amf_server extends webservice_zend_server {
/**
* Contructor
* @param bool $simple use simple authentication
* @param integer $authmethod authentication method - one of WEBSERVICE_AUTHMETHOD_*
*/
public function __construct($simple) {
public function __construct($authmethod) {
require_once 'Zend/Amf/Server.php';
parent::__construct($simple, 'Zend_Amf_Server');
parent::__construct($authmethod, 'Zend_Amf_Server');
$this->wsname = 'amf';
}
protected function init_service_class(){
parent::init_service_class();
parent::init_service_class();
//allow access to data about methods available.
$this->zend_server->setClass( "MethodDescriptor" );
MethodDescriptor::$classnametointrospect = $this->service_class;
}

protected function service_class_method_body($function, $params){
$params = "webservice_amf_server::cast_objects_to_array($params)";
$externallibcall = $function->classname.'::'.$function->methodname.'('.$params.')';
$descriptionmethod = $function->methodname.'_returns()';
$callforreturnvaluedesc = $function->classname.'::'.$descriptionmethod;
return
if ($params){
$params = "webservice_amf_server::cast_objects_to_array($params)";
}
$externallibcall = $function->classname.'::'.$function->methodname.'('.$params.')';
$descriptionmethod = $function->methodname.'_returns()';
$callforreturnvaluedesc = $function->classname.'::'.$descriptionmethod;
return
' return webservice_amf_server::validate_and_cast_values('.$callforreturnvaluedesc.', '.$externallibcall.');';
}
/**
Expand All @@ -80,9 +82,9 @@ protected function service_class_method_body($function, $params){
* @return mixed params with added defaults for optional items, invalid_parameters_exception thrown if any problem found
*/
public static function validate_and_cast_values($description, $value) {
if (is_null($description)){
return;
}
if (is_null($description)){
return;
}
if ($description instanceof external_value) {
if (is_array($value) or is_object($value)) {
throw new invalid_return_value_exception('Scalar type expected, array or object received.');
Expand Down Expand Up @@ -136,27 +138,27 @@ public static function validate_and_cast_values($description, $value) {
throw new invalid_return_value_exception('Invalid external api description.');
}
}
/**
* Recursive function to recurse down into a complex variable and convert all
* objects to arrays. Doesn't recurse down into objects or cast objects other than stdClass
* which is represented in Flash / Flex as an object.
* @param mixed $params value to cast
* @return mixed Cast value
*/
public static function cast_objects_to_array($params){
if ($params instanceof stdClass){
$params = (array)$params;
}
if (is_array($params)){
$toreturn = array();
foreach ($params as $key=> $param){
$toreturn[$key] = self::cast_objects_to_array($param);
}
return $toreturn;
} else {
return $params;
}
}
/**
* Recursive function to recurse down into a complex variable and convert all
* objects to arrays. Doesn't recurse down into objects or cast objects other than stdClass
* which is represented in Flash / Flex as an object.
* @param mixed $params value to cast
* @return mixed Cast value
*/
public static function cast_objects_to_array($params){
if ($params instanceof stdClass){
$params = (array)$params;
}
if (is_array($params)){
$toreturn = array();
foreach ($params as $key=> $param){
$toreturn[$key] = self::cast_objects_to_array($param);
}
return $toreturn;
} else {
return $params;
}
}
/**
* Set up zend service class
* @return void
Expand Down
2 changes: 1 addition & 1 deletion webservice/amf/server.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
die;
}

$server = new webservice_amf_server(false);
$server = new webservice_amf_server(WEBSERVICE_AUTHMETHOD_PERMANENT_TOKEN);
$server->run();
die;

2 changes: 1 addition & 1 deletion webservice/amf/simpleserver.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
die;
}

$server = new webservice_amf_server(true);
$server = new webservice_amf_server(WEBSERVICE_AUTHMETHOD_USERNAME);
$server->run();
die;

Expand Down
Loading

0 comments on commit 2d0acbd

Please sign in to comment.