From 1ce2da5836d0d9a2af0360ac6fb0a0eb79800912 Mon Sep 17 00:00:00 2001 From: peterbulmer Date: Sun, 3 Aug 2008 23:24:12 +0000 Subject: [PATCH] MDL-12558 modify emails as they are being sent replace urls in-place to direct users to their idp first --- auth/mnet/jump.php | 10 +++++++-- lib/db/install.xml | 7 +++--- lib/db/upgrade.php | 15 +++++++++++++ lib/moodlelib.php | 25 ++++++++++++++++++++- mnet/lib.php | 56 ++++++++++++++++++++++++++++++++++++++++++++++ version.php | 2 +- 6 files changed, 108 insertions(+), 7 deletions(-) diff --git a/auth/mnet/jump.php b/auth/mnet/jump.php index 2504723de8..f7796a5ea5 100644 --- a/auth/mnet/jump.php +++ b/auth/mnet/jump.php @@ -14,7 +14,7 @@ require_once dirname(dirname(dirname(__FILE__))) . '/config.php'; -require_login(); +require_login(SITEID,false); if (!is_enabled_auth('mnet')) { print_error('mnetdisable'); @@ -22,9 +22,15 @@ if (!is_enabled_auth('mnet')) { // grab the GET params - wantsurl could be anything - take it // with PARAM_RAW -$hostid = required_param('hostid', PARAM_INT); +$hostid = optional_param('hostid', '0', PARAM_INT); +$hostwwwroot = optional_param('hostwwwroot', '', PARAM_URL); $wantsurl = optional_param('wantsurl', '', PARAM_RAW); +// If hostid hasn't been specified, try getting it using wwwroot +if (!$hostid) { + $hostid = $DB->get_field('mnet_host', 'id', array('wwwroot' => $hostwwwroot)); +} + // start the mnet session and redirect browser to remote URL $mnetauth = get_auth_plugin('mnet'); $url = $mnetauth->start_jump_session($hostid, $wantsurl); diff --git a/lib/db/install.xml b/lib/db/install.xml index 0154ff5aad..cc7d1ffc1c 100644 --- a/lib/db/install.xml +++ b/lib/db/install.xml @@ -995,7 +995,8 @@ - + + @@ -1840,8 +1841,8 @@ - - + + diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index d3cfa033fd..67ea3ed514 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -551,6 +551,21 @@ function xmldb_main_upgrade($oldversion=0) { upgrade_main_savepoint($result, 2008073114); } + if ($result && $oldversion < 2008080400) { + // Add field ssl_jump_url to mnet application, and populate existing default applications + $table = new xmldb_table('mnet_application'); + $field = new xmldb_field('sso_jump_url'); + if (!$dbman->field_exists($table, $field)) { + $field->set_attributes(XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null); + $result = $result && $dbman->add_field($table, $field); + $result = $result && $DB->set_field('mnet_application', 'sso_jump_url', '/auth/mnet/jump.php', array('name' => 'moodle')); + $result = $result && $DB->set_field('mnet_application', 'sso_jump_url', '/auth/xmlrpc/jump.php', array('name' => 'mahara')); + } + + /// Main savepoint reached + upgrade_main_savepoint($result, 2008080400); + } + return $result; } diff --git a/lib/moodlelib.php b/lib/moodlelib.php index fe3080fd1b..b4999efbe2 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -3993,7 +3993,8 @@ function &get_mailer($action='get') { */ function email_to_user($user, $from, $subject, $messagetext, $messagehtml='', $attachment='', $attachname='', $usetrueaddress=true, $replyto='', $replytoname='', $wordwrapwidth=79) { - global $CFG, $FULLME; + global $CFG, $FULLME, $IDPJUMPURL; + static $mnetjumps = array(); if (empty($user)) { return false; @@ -4018,6 +4019,28 @@ function email_to_user($user, $from, $subject, $messagetext, $messagehtml='', $a return false; } + // If the user is a remote mnet user, parse the email text for URL to the + // wwwroot and modify the url to direct the user's browser to login at their + // home site (identity provider - idp) before hitting the link itself + if ($user->mnethostid > 1) { + require_once($CFG->dirroot.'/mnet/lib.php'); + // Form the request url to hit the idp's jump.php + if (isset($mnetjumps[$user->mnethostid])) { + $IDPJUMPURL = $mnetjumps[$user->mnethostid]; + } else { + $idp = mnet_get_peer_host($user->mnethostid); + $idpjumppath = mnet_get_app_jumppath($idp->applicationid); + $IDPJUMPURL = $idp->wwwroot . $idpjumppath . '?hostwwwroot=' . $CFG->wwwroot . '&wantsurl='; + $mnetjumps[$user->mnethostid] = $IDPJUMPURL; + } + + $messagetext = preg_replace_callback("%($CFG->wwwroot[^[:space:]]*)%", + 'mnet_sso_apply_indirection', + $messagetext); + $messagehtml = preg_replace_callback("%href=[\"'`]($CFG->wwwroot[\w_:\?=#&@/;.~-]*)[\"'`]%", + 'mnet_sso_apply_indirection', + $messagehtml); + } $mail =& get_mailer(); if (!empty($mail->SMTPDebug)) { diff --git a/mnet/lib.php b/mnet/lib.php index 05e9559651..9998df0792 100644 --- a/mnet/lib.php +++ b/mnet/lib.php @@ -568,4 +568,60 @@ function mnet_update_sso_access_control($username, $mnet_host_id, $accessctrl) { } return true; } + +function mnet_get_peer_host ($mnethostid) { + global $DB; + static $hosts; + if (!isset($hosts[$mnethostid])) { + $host = $DB->get_record('mnet_host', array('id' => $mnethostid)); + $hosts[$mnethostid] = $host; + } + return $hosts[$mnethostid]; +} + +/** + * Inline function to modify a url string so that mnet users are requested to + * log in at their mnet identity provider (if they are not already logged in) + * before ultimately being directed to the original url. + * + * uses global IDPJUMPURL - the url which user should initially be directed to + * @param array $url array with 2 elements + * 0 - context the url was taken from, possibly just the url, possibly href="url" + * 1 - the destination url + * @return string the url the remote user should be supplied with. + */ +function mnet_sso_apply_indirection ($url) { + global $IDPJUMPURL; + + $localpart=''; + $urlparts = parse_url($url[1]); + if($urlparts) { + if (isset($urlparts['path'])) { + $localpart .= $urlparts['path']; + } + if (isset($urlparts['query'])) { + $localpart .= '?'.$urlparts['query']; + } + if (isset($urlparts['fragment'])) { + $localpart .= '#'.$urlparts['fragment']; + } + } + $indirecturl = $IDPJUMPURL . urlencode($localpart); + //If we matched on more than just a url (ie an html link), return the url to an href format + if ($url[0] != $url[1]) { + $indirecturl = 'href="'.$indirecturl.'"'; + } + return $indirecturl; +} + +function mnet_get_app_jumppath ($applicationid) { + global $DB; + static $appjumppaths; + if (!isset($appjumppaths[$applicationid])) { + $ssojumpurl = $DB->get_field('mnet_application', 'sso_jump_url', array('id' => $applicationid)); + $appjumppaths[$applicationid] = $ssojumpurl; + } + return $appjumppaths[$applicationid]; +} + ?> diff --git a/version.php b/version.php index abe82dc528..3dc0984a68 100644 --- a/version.php +++ b/version.php @@ -6,7 +6,7 @@ // This is compared against the values stored in the database to determine // whether upgrades should be performed (see lib/db/*.php) - $version = 2008073114; // YYYYMMDD = date of the last version bump + $version = 2008080400; // YYYYMMDD = date of the last version bump // XX = daily increments $release = '2.0 dev (Build: 20080803)'; // Human-friendly version name -- 2.39.5