From 6e4985bf0f0a298958211a29e5a05bae9f689724 Mon Sep 17 00:00:00 2001 From: Jun Pataleta Date: Fri, 23 Nov 2018 11:28:17 +0800 Subject: [PATCH 1/2] MDL-62973 auth_shibboleth: Make login form look nicer * Convert login form to a mustache template * Bring logic in auth/shibboleth/login.php * Replace usage of $_POST variable with optional_param() * Remove unused index_form.html --- auth/shibboleth/auth.php | 7 +- auth/shibboleth/index_form.html | 98 ------------- auth/shibboleth/lang/en/auth_shibboleth.php | 2 +- auth/shibboleth/login.php | 99 ++++++++++---- auth/shibboleth/templates/login_form.mustache | 129 ++++++++++++++++++ 5 files changed, 205 insertions(+), 130 deletions(-) delete mode 100644 auth/shibboleth/index_form.html create mode 100644 auth/shibboleth/templates/login_form.mustache diff --git a/auth/shibboleth/auth.php b/auth/shibboleth/auth.php index 39ca032b44e..ed1b0d36f37 100644 --- a/auth/shibboleth/auth.php +++ b/auth/shibboleth/auth.php @@ -308,9 +308,9 @@ class auth_plugin_shibboleth extends auth_plugin_base { /** * Sets the standard SAML domain cookie that is also used to preselect - * the right entry on the local wayf + * the right entry on the local way * - * @param IdP identifiere + * @param string $selectedIDP IDP identifier */ function set_saml_cookie($selectedIDP) { if (isset($_COOKIE['_saml_idp'])) @@ -325,9 +325,8 @@ class auth_plugin_shibboleth extends auth_plugin_base { setcookie ('_saml_idp', generate_cookie_value($IDPArray), time() + (100*24*3600)); } - /** + /** * Prints the option elements for the select element of the drop down list - * */ function print_idp_list(){ $config = get_config('auth_shibboleth'); diff --git a/auth/shibboleth/index_form.html b/auth/shibboleth/index_form.html deleted file mode 100644 index 9f1e23e6ef8..00000000000 --- a/auth/shibboleth/index_form.html +++ /dev/null @@ -1,98 +0,0 @@ - -
-
- - -

login_name) && !empty($config->login_name)){ - echo $config->login_name; - } else { - print_string("auth_shibboleth_login_long", "auth_shibboleth"); - } - ?>

-
-
- '; - echo $OUTPUT->error_text($errormsg); - echo '
'; - } - - ?> -
-

-
-

" accesskey="s" />

-
-

- email); - ?> -

-
-
-
- -guestloginbutton) { ?> -
-
- -
-
-
- - - - " /> -
-
-
- -
- - - -
-

-
-registerauth == 'email') { - if (!empty($config->auth_instructions)) { - echo format_text($config->auth_instructions); - } else { - print_string("loginsteps", "", "signup.php"); - } ?> -
-
-
" />
-
-
-registerauth)) { - echo format_text($config->auth_instructions); ?> -
-
-
" />
-
-
-auth_instructions); - } ?> -
-
- - diff --git a/auth/shibboleth/lang/en/auth_shibboleth.php b/auth/shibboleth/lang/en/auth_shibboleth.php index 8ef9ec1b2bc..fd8b7470508 100644 --- a/auth/shibboleth/lang/en/auth_shibboleth.php +++ b/auth/shibboleth/lang/en/auth_shibboleth.php @@ -41,7 +41,7 @@ $string['auth_shib_convert_data_warning'] = 'The file does not exist or is not r $string['auth_shib_changepasswordurl'] = 'Password-change URL'; $string['auth_shib_idp_list'] = 'Identity providers'; $string['auth_shib_idp_list_description'] = 'Provide a list of Identity Provider entityIDs to let the user choose from on the login page.
On each line there must be a comma-separated tuple for entityID of the IdP (see the Shibboleth metadata file) and Name of IdP as it shall be displayed in the drop-down list.
As an optional third parameter you can add the location of a Shibboleth session initiator that shall be used in case your Moodle installation is part of a multi federation setup.'; -$string['auth_shib_instructions'] = 'Use the Shibboleth login to get access via Shibboleth, if your institution supports it.
Otherwise, use the normal login form shown here.'; +$string['auth_shib_instructions'] = 'Use the Shibboleth login to get access via Shibboleth, if your institution supports it. Otherwise, use the normal login form shown here.'; $string['auth_shib_instructions_help'] = 'Here you should provide custom instructions for your users to explain Shibboleth. It will be shown on the login page in the instructions section. The instructions must include a link to "{$a}" that users click when they want to log in.'; $string['auth_shib_instructions_key'] = 'Login instructions'; $string['auth_shib_integrated_wayf'] = 'Moodle WAYF service'; diff --git a/auth/shibboleth/login.php b/auth/shibboleth/login.php index 6877fcbcd42..d4fc639ce5b 100644 --- a/auth/shibboleth/login.php +++ b/auth/shibboleth/login.php @@ -3,10 +3,9 @@ require_once("../../config.php"); require_once($CFG->dirroot."/auth/shibboleth/auth.php"); - //initialize variables - $errormsg = ''; + $idp = optional_param('idp', null, PARAM_RAW); -/// Check for timed out sessions + // Check for timed out sessions. if (!empty($SESSION->has_timed_out)) { $session_has_timed_out = true; $SESSION->has_timed_out = false; @@ -14,8 +13,8 @@ $session_has_timed_out = false; } - -/// Define variables used in page + // Define variables used in page. + $isvalid = true; $site = get_site(); $loginsite = get_string("loginsite"); @@ -24,33 +23,31 @@ $config = get_config('auth_shibboleth'); if (!empty($CFG->registerauth) or is_enabled_auth('none') or !empty($config->auth_instructions)) { - $show_instructions = true; + $showinstructions = true; } else { - $show_instructions = false; + $showinstructions = false; } - $IdPs = get_idp_list($config->organization_selection); - if (isset($_POST['idp']) && isset($IdPs[$_POST['idp']])){ - $selectedIdP = $_POST['idp']; - set_saml_cookie($selectedIdP); + $idplist = get_idp_list($config->organization_selection); + if (isset($idp)) { + if (isset($idplist[$idp])) { + set_saml_cookie($idp); - // Redirect to SessionInitiator with entityID as argument - if (isset($IdPs[$selectedIdP][1]) && !empty($IdPs[$selectedIdP][1])) { - // For Shibbolet 1.x Service Providers - header('Location: '.$IdPs[$selectedIdP][1].'?providerId='. urlencode($selectedIdP) .'&target='. urlencode($CFG->wwwroot.'/auth/shibboleth/index.php')); + $targeturl = new moodle_url('/auth/shibboleth/index.php'); + $idpinfo = $idplist[$idp]; - // For Shibbolet 2.x Service Providers - // header('Location: '.$IdPs[$selectedIdP][1].'?entityID='. urlencode($selectedIdP) .'&target='. urlencode($CFG->wwwroot.'/auth/shibboleth/index.php')); + // Redirect to SessionInitiator with entityID as argument. + if (isset($idpinfo[1]) && !empty($idpinfo[1])) { + $sso = $idpinfo[1]; + } else { + $sso = '/Shibboleth.sso'; + } + // For Shibboleth 1.x Service Providers. + header('Location: ' . $sso . '?providerId=' . urlencode($idp) . '&target=' . urlencode($targeturl->out())); } else { - // For Shibbolet 1.x Service Providers - header('Location: /Shibboleth.sso?providerId='. urlencode($selectedIdP) .'&target='. urlencode($CFG->wwwroot.'/auth/shibboleth/index.php')); - - // For Shibboleth 2.x Service Providers - // header('Location: /Shibboleth.sso/DS?entityID='. urlencode($selectedIdP) .'&target='. urlencode($CFG->wwwroot.'/auth/shibboleth/index.php')); + $isvalid = false; } - } elseif (isset($_POST['idp']) && !isset($IdPs[$_POST['idp']])) { - $errormsg = get_string('auth_shibboleth_errormsg', 'auth_shibboleth'); } $loginsite = get_string("loginsite"); @@ -60,6 +57,7 @@ $PAGE->navbar->add($loginsite); $PAGE->set_title("$site->fullname: $loginsite"); $PAGE->set_heading($site->fullname); + $PAGE->set_pagelayout('login'); echo $OUTPUT->header(); @@ -72,9 +70,56 @@ echo $OUTPUT->confirm(get_string('alreadyloggedin', 'error', fullname($USER)), $logout, $continue); echo $OUTPUT->box_end(); } else { - include("index_form.html"); + // Print login page. + $selectedidp = '-'; + if (isset($_COOKIE['_saml_idp'])) { + $idpcookie = generate_cookie_array($_COOKIE['_saml_idp']); + do { + $selectedidp = array_pop($idpcookie); + } while (!isset($idplist[$selectedidp]) && count($idpcookie) > 0); + } + + $idps = []; + foreach ($idplist as $value => $data) { + $name = reset($data); + $selected = $value === $selectedidp; + $idps[] = (object)[ + 'name' => $name, + 'value' => $value, + 'selected' => $selected + ]; + } + + // Whether the user can sign up. + $cansignup = !empty($CFG->registerauth); + // Default instructions. + $instructions = format_text($config->auth_instructions); + if (is_enabled_auth('none')) { + $instructions = get_string('loginstepsnone'); + } else if ($cansignup) { + if ($CFG->registerauth === 'email' && empty($instructions)) { + $instructions = get_string('loginsteps'); + } + } + + // Build the template context data. + $templatedata = (object)[ + 'adminemail' => get_admin()->email, + 'cansignup' => $cansignup, + 'guestlogin' => $CFG->guestloginbutton, + 'guestloginurl' => new moodle_url('/login/index.php'), + 'idps' => $idps, + 'instructions' => $instructions, + 'loginname' => $config->login_name ?? null, + 'logintoken' => \core\session\manager::get_login_token(), + 'loginurl' => new moodle_url('/auth/shibboleth/login.php'), + 'showinstructions' => $showinstructions, + 'signupurl' => new moodle_url('/login/signup.php'), + 'isvalid' => $isvalid + ]; + + // Render the login form. + echo $OUTPUT->render_from_template('auth_shibboleth/login_form', $templatedata); } echo $OUTPUT->footer(); - - diff --git a/auth/shibboleth/templates/login_form.mustache b/auth/shibboleth/templates/login_form.mustache new file mode 100644 index 00000000000..230f6151df7 --- /dev/null +++ b/auth/shibboleth/templates/login_form.mustache @@ -0,0 +1,129 @@ +{{! + This file is part of Moodle - http://moodle.org/ + + Moodle is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Moodle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Moodle. If not, see . +}} +{{! + @template auth_shibboleth/login_form + + Template for the Shibboleth authentication plugin's login form. + + Classes required for JS: + * none + + Data attributes required for JS: + * none + + Context variables required for this template: + * adminemail String The Administrator's email address. + * cansignup Boolean Whether a new user can sign up for an account. + * guestlogin Boolean Whether to show the guest login section. + * guestloginurl String The URL for guest login. + * idps Array The list of identity providers for the Shibboleth authentication plugin in value-name pairs per IDP. + * instructions String Signup instructions. + * isvalid Boolean Whether form validation passes. + * loginname String The custom login name. + * logintoken String The login token. + * loginurl String The login URL. + * showinstructions Boolean Whether to show additional login instructions. + * signupurl String The signup URL. + + Example context (json): + { + "loginurl": "#", + "guestloginurl": "#", + "guestlogin": true, + "idps": [ + { "value": 1, "name": "IDP 1" }, + { "value": 2, "name": "IDP 2", "selected": true }, + { "value": 3, "name": "IDP 3" } + ], + "showinstructions": true, + "logintoken": "abcde", + "adminemail": "admin@example.com", + "loginname": "Shib auth", + "cansignup": true, + "signupurl": "#", + "instructions": "Sign up here", + "isvalid": false + } +}} + +
+
+
+

+ {{#loginname}}{{.}}{{/loginname}} + {{^loginname}}{{#str}}auth_shibboleth_login_long, auth_shibboleth{{/str}}{{/loginname}} +

+
+
+
+
+
+ + +
+ {{#str}}auth_shibboleth_errormsg, auth_shibboleth{{/str}} +
+
+ +

+ {{#str}}auth_shib_contact_administrator, auth_shibboleth, {{adminemail}}{{/str}} +

+
+
+ {{#guestlogin}} +
+

+ {{#str}}someallowguest, moodle{{/str}} +

+
+
+ + + + +
+
+
+ {{/guestlogin}} +
+
+
+ {{#showinstructions}} +
+
+

{{#str}}firsttime, moodle{{/str}}

+

+ {{{instructions}}} +

+ {{#cansignup}} +
+ +
+ {{/cansignup}} +
+
+ {{/showinstructions}} +
From 0cd5b1652deb1598e1fa1f3315368f7ad12a0f7a Mon Sep 17 00:00:00 2001 From: Jun Pataleta Date: Fri, 7 Dec 2018 16:29:10 +0800 Subject: [PATCH 2/2] MDL-62973 auth_shibboleth: Delete unused print_idp_list() function This is only being used by the now-deleted login_form.html. No point keeping it. --- auth/shibboleth/auth.php | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/auth/shibboleth/auth.php b/auth/shibboleth/auth.php index ed1b0d36f37..c52ad129135 100644 --- a/auth/shibboleth/auth.php +++ b/auth/shibboleth/auth.php @@ -326,39 +326,11 @@ class auth_plugin_shibboleth extends auth_plugin_base { } /** - * Prints the option elements for the select element of the drop down list - */ - function print_idp_list(){ - $config = get_config('auth_shibboleth'); - - $IdPs = get_idp_list($config->organization_selection); - if (isset($_COOKIE['_saml_idp'])){ - $idp_cookie = generate_cookie_array($_COOKIE['_saml_idp']); - do { - $selectedIdP = array_pop($idp_cookie); - } while (!isset($IdPs[$selectedIdP]) && count($idp_cookie) > 0); - - } else { - $selectedIdP = '-'; - } - - foreach($IdPs as $IdP => $data){ - if ($IdP == $selectedIdP){ - echo ''; - } else { - echo ''; - } - } - } - - - /** * Generate array of IdPs from Moodle Shibboleth settings * * @param string Text containing tuble/triple of IdP entityId, name and (optionally) session initiator * @return array Identifier of IdPs and their name/session initiator */ - function get_idp_list($organization_selection) { $idp_list = array();