Merge branch 'MDL-62973-master' of git://github.com/junpataleta/moodle

This commit is contained in:
Eloy Lafuente (stronk7) 2019-02-05 00:08:02 +01:00
commit 77017d1138
5 changed files with 205 additions and 158 deletions

View File

@ -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,41 +325,12 @@ 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');
$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 '<option value="'.$IdP.'" selected="selected">'.$data[0].'</option>';
} else {
echo '<option value="'.$IdP.'">'.$data[0].'</option>';
}
}
}
/**
/**
* 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();

View File

@ -1,98 +0,0 @@
<?php
$config = get_config('auth_shibboleth');
if ($show_instructions) {
$columns = 'twocolumns';
} else {
$columns = 'onecolumn';
}
?>
<div class="loginbox clearfix <?php echo $columns ?>">
<div class="loginpanel">
<!--<h2><?php print_string("returningtosite") ?></h2>-->
<h2><?php
if (isset($config->login_name) && !empty($config->login_name)){
echo $config->login_name;
} else {
print_string("auth_shibboleth_login_long", "auth_shibboleth");
}
?></h2>
<div class="subcontent loginsub">
<div class="desc">
<?php
if (!empty($errormsg)) {
echo '<div class="loginerrors">';
echo $OUTPUT->error_text($errormsg);
echo '</div>';
}
?>
<div class="guestsub">
<p><label for="idp"><?php print_string("auth_shibboleth_select_organization", "auth_shibboleth"); ?></label></p>
<form action="login.php" method="post" id="guestlogin">
<select id="idp" name="idp">
<option value="-" ><?php print_string("auth_shibboleth_select_member", "auth_shibboleth"); ?></option>
<?php
print_idp_list();
?>
</select><p><input type="submit" value="<?php print_string("select"); ?>" accesskey="s" /></p>
</form>
<p>
<?php
print_string("auth_shib_contact_administrator", "auth_shibboleth", get_admin()->email);
?>
</p>
</div>
</div>
</div>
<?php if ($CFG->guestloginbutton) { ?>
<div class="subcontent guestsub">
<div class="desc">
<?php print_string("someallowguest") ?>
</div>
<form action="../../login/index.php" method="post" id="guestlogin">
<div class="guestform">
<input type="hidden" name="logintoken" value="<?php echo s(\core\session\manager::get_login_token()); ?>" />
<input type="hidden" name="username" value="guest" />
<input type="hidden" name="password" value="guest" />
<input type="submit" value="<?php print_string("loginguest") ?>" />
</div>
</form>
</div>
<?php } ?>
</div>
<?php if ($show_instructions) { ?>
<div class="signuppanel">
<h2><?php print_string("firsttime") ?></h2>
<div class="subcontent">
<?php if (is_enabled_auth('none')) { // instructions override the rest for security reasons
print_string("loginstepsnone");
} else if ($CFG->registerauth == 'email') {
if (!empty($config->auth_instructions)) {
echo format_text($config->auth_instructions);
} else {
print_string("loginsteps", "", "signup.php");
} ?>
<div class="signupform">
<form action="../../login/signup.php" method="get" id="signup">
<div><input type="submit" value="<?php print_string("startsignup") ?>" /></div>
</form>
</div>
<?php } else if (!empty($CFG->registerauth)) {
echo format_text($config->auth_instructions); ?>
<div class="signupform">
<form action="../../login/signup.php" method="get" id="signup">
<div><input type="submit" value="<?php print_string("startsignup") ?>" /></div>
</form>
</div>
<?php } else {
echo format_text($config->auth_instructions);
} ?>
</div>
</div>
<?php } ?>
</div>

View File

@ -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.<br />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.<br />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 <a href="{$a}">Shibboleth login</a> to get access via Shibboleth, if your institution supports it.<br />Otherwise, use the normal login form shown here.';
$string['auth_shib_instructions'] = 'Use the <a href="{$a}">Shibboleth login</a> 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 "<b>{$a}</b>" that users click when they want to log in.';
$string['auth_shib_instructions_key'] = 'Login instructions';
$string['auth_shib_integrated_wayf'] = 'Moodle WAYF service';

View File

@ -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();

View File

@ -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 <http://www.gnu.org/licenses/>.
}}
{{!
@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
}
}}
<div class="my-1 my-sm-5"></div>
<div class="container">
<div class="card">
<h2 class="card-header">
{{#loginname}}{{.}}{{/loginname}}
{{^loginname}}{{#str}}auth_shibboleth_login_long, auth_shibboleth{{/str}}{{/loginname}}
</h2>
<div class="card-body">
<div class="row justify-content-center m-l-1 m-r-1 m-b-1">
<div class="col-md-5">
<form action="{{loginurl}}" method="post" id="login">
<div class="form-group">
<label for="idp">{{#str}}auth_shibboleth_select_organization, auth_shibboleth{{/str}}</label>
<select id="idp" name="idp" class="form-control input-block-level {{^isvalid}}is-invalid{{/isvalid}}">
<option value="-">{{#str}}auth_shibboleth_select_member, auth_shibboleth{{/str}}</option>
{{#idps}}
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
{{/idps}}
</select>
<div class="invalid-feedback text-danger m-b-1" {{#isvalid}}hidden{{/isvalid}}>
{{#str}}auth_shibboleth_errormsg, auth_shibboleth{{/str}}
</div>
</div>
<button type="submit" class="btn btn-primary btn-block m-b-1" accesskey="s">
{{#str}}select, moodle{{/str}}
</button>
<p class="form-text text-muted m-t-1 m-b-1">
{{#str}}auth_shib_contact_administrator, auth_shibboleth, {{adminemail}}{{/str}}
</p>
</form>
</div>
{{#guestlogin}}
<div class="col-md-5">
<p>
{{#str}}someallowguest, moodle{{/str}}
</p>
<form action="{{guestloginurl}}" method="post" id="guestlogin">
<div class="guestform">
<input type="hidden" name="logintoken" value="{{logintoken}}">
<input type="hidden" name="username" value="guest">
<input type="hidden" name="password" value="guest">
<button type="submit" class="btn btn-secondary btn-block">
{{#str}}loginguest, moodle{{/str}}
</button>
</div>
</form>
</div>
{{/guestlogin}}
</div>
</div>
</div>
{{#showinstructions}}
<div class="card m-t-1">
<div class="card-body m-l-1 m-r-1 m-b-1">
<h2 class="card-title">{{#str}}firsttime, moodle{{/str}}</h2>
<p>
{{{instructions}}}
</p>
{{#cansignup}}
<form action="{{signupurl}}" method="get" id="signup">
<button type="submit" class="btn btn-secondary">{{#str}}startsignup, moodle{{/str}}</button>
</form>
{{/cansignup}}
</div>
</div>
{{/showinstructions}}
</div>