Skip to content

Commit

Permalink
New release of the Auth and Enrol SAML plugins. Code improvements and…
Browse files Browse the repository at this point in the history
… fix minor bugs
  • Loading branch information
pitbulk committed Jul 20, 2015
1 parent 40edab6 commit ef3ad62
Show file tree
Hide file tree
Showing 16 changed files with 98 additions and 162 deletions.
51 changes: 31 additions & 20 deletions auth/saml/auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ function auth_plugin_saml() {
* @return bool Authentication success or failure.
*/
function user_login($username, $password) {
global $SESSION;
// if true, user_login was initiated by saml/index.php
if(isset($GLOBALS['saml_login']) && $GLOBALS['saml_login']) {
unset($GLOBALS['saml_login']);
if(isset($SESSION->auth_saml_login) && $SESSION->auth_saml_login) {
unset($SESSION->auth_saml_login);
return TRUE;
}

Expand All @@ -60,7 +61,8 @@ function user_login($username, $password) {
* @return array $result Associative array of user data
*/
function get_userinfo($username) {
if($login_attributes = $GLOBALS['saml_login_attributes']) {
global $SESSION;
if($login_attributes = $SESSION->auth_saml_login_attributes) {
$attributemap = $this->get_attributes();
$result = array();

Expand All @@ -71,7 +73,7 @@ function get_userinfo($username) {
$result[$key] = '';
}
}
unset($GLOBALS['saml_login_attributes']);
unset($SESSION->auth_saml_login_attributes);

$result["username"] = $username;
return $result;
Expand Down Expand Up @@ -124,8 +126,16 @@ function can_change_password() {
return false;
}

function loginpage_hook() {
function pre_loginpage_hook() {
// If Force Login is on then we can safely jump directly to the SAML IdP
if (isset($this->config->autologin) && $this->config->autologin) {
global $SESSION;
$samlurl = $CFG->wwwroot.'/auth/saml/index.php?wantsurl=' . urlencode($SESSION->wantsurl);
redirect($samlurl);
}
}

function loginpage_hook() {
global $CFG;

if (empty($CFG->alternateloginurl) && !(isset($_GET['saml']) && $_GET['saml'] === 'false')) {
Expand All @@ -134,14 +144,15 @@ function loginpage_hook() {

// Prevent username from being shown on login page after logout
$CFG->nolastloggedin = true;
$GLOBALS['CFG']->nolastloggedin = true;
}

function logoutpage_hook() {
global $CFG;

if(isset($this->config->dosinglelogout) && $this->config->dosinglelogout) {
set_moodle_cookie('nobody');
require_logout();
redirect($GLOBALS['CFG']->wwwroot.'/auth/saml/index.php?logout=1');
redirect($CFG->wwwroot.'/auth/saml/index.php?logout=1');
}
}

Expand Down Expand Up @@ -244,7 +255,7 @@ function validate_form($form, &$err) {
$saml_role_form_id = array();
if (isset($form->update_roles_id)) {
foreach ($form->update_roles_id as $role_id) {
$role = $form->{'role_' . $role_id};
$role = $form->{'role_' . $role_id};
if (!empty($role[0]) && !empty($role[1])) {
$lms_role_form_id[] = $role[0];
$saml_role_form_id[] = $role[1];
Expand All @@ -258,12 +269,12 @@ function validate_form($form, &$err) {
}
if (isset($form->new_roles_total)) {
for ($i=0; $i <= $form->new_roles_total; $i++) {
$new_course = $form->{'new_role' . $i};
$new_course = $form->{'new_role' . $i};
if (!empty($new_role[1])) {
$lms_role_form_id[] = $new_role[0];
$saml_role_form_id[] = $new_role[1];
}
}
}
}
//$err['role_mapping']['lms'] = array_diff_key($lms_role_form_id, array_unique($lms_role_form_id));
$err['role_mapping']['saml'] = array_diff_key($saml_role_form_id, array_unique($saml_role_form_id));
Expand All @@ -273,7 +284,7 @@ function validate_form($form, &$err) {
unset($err['role_mapping']);
}
}
}
}
}

/**
Expand All @@ -300,7 +311,7 @@ function process_config($config) {
exit();
}

if(isset($config->initialize_roles)) {
if(isset($config->initialize_roles)) {
global $CFG;
$this->initialize_roles($DB, $err);
header('Location: ' . $CFG->wwwroot . '/admin/auth_config.php?auth=saml#rolemapping');
Expand Down Expand Up @@ -364,22 +375,22 @@ function process_config($config) {
if (!isset ($config->ignoreinactivecourses)) {
$config->ignoreinactivecourses = '';
}
if (!isset ($config->externalcoursemappingdsn)) {
if (!isset ($config->externalcoursemappingdsn)) {
$config->externalcoursemappingdsn = '';
}
if (!isset ($config->externalrolemappingdsn)) {
if (!isset ($config->externalrolemappingdsn)) {
$config->externalrolemappingdsn = '';
}
if (!isset ($config->externalcoursemappingsql)) {
if (!isset ($config->externalcoursemappingsql)) {
$config->externalcoursemappingsql = '';
}
if (!isset ($config->externalrolemappingsql)) {
if (!isset ($config->externalrolemappingsql)) {
$config->externalrolemappingsql = '';
}

// Save saml settings in a file
// Save saml settings in a file
$saml_param_encoded = json_encode($saml_param);
file_put_contents(dirname(__FILE__) . '/saml_config.php', $saml_param_encoded);
file_put_contents($CFG->dataroot.'/saml_config.php', $saml_param_encoded);

// Also adding this parameters in database but no need it really.
set_config('samllib', $saml_param->samllib, 'auth/saml');
Expand Down Expand Up @@ -408,7 +419,7 @@ function process_config($config) {
else if($config->supportcourses == 'internal') {

$table_course_mapping = $this->get_course_mapping_xmldb();
$table_role_mapping = $this->get_role_mapping_xmldb();
$table_role_mapping = $this->get_role_mapping_xmldb();

if(!$dbman->table_exists($table_course_mapping)) {
$this->create_course_mapping_db($DB, $err);
Expand Down Expand Up @@ -456,7 +467,7 @@ function process_config($config) {
$DB->execute($sql);
}
catch (Exception $e) {
$err['course_mapping_db'][] = get_string("auth_saml_error_executing", "auth_saml").$sql;
$err['course_mapping_db'][] = get_string("auth_saml_error_executing", "auth_saml").$sql;
}
}
}
Expand Down
11 changes: 7 additions & 4 deletions auth/saml/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@
require_once("roles.php");

// Get saml paramters stored in the saml_config.php
if(file_exists('saml_config.php')) {
if(file_exists($CFG->dataroot.'/saml_config.php')) {
$contentfile = file_get_contents($CFG->dataroot.'/saml_config.php');
$saml_param = json_decode($contentfile);
} else if (file_exists('saml_config.php')) {
$contentfile = file_get_contents('saml_config.php');
$saml_param = json_decode($contentfile);
$saml_param = json_decode($contentfile);
} else {
$saml_param = new stdClass();
}
Expand Down Expand Up @@ -125,14 +128,14 @@
if (isset($err) && !empty($err)) {

require_once('error.php');
saml_error($err, false, $config->samllogfile);
auth_saml_error($err, false, $config->samllogfile);

echo '
<tr>
<td class="center" colspan="4" style="background-color: red; color: white;text-">
';
if(isset($err['reset'])) {
echo $err['reset'];
echo $err['reset'];
}
else {
print_string("auth_saml_form_error", "auth_saml");
Expand Down
16 changes: 8 additions & 8 deletions auth/saml/error.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

function saml_error($err, $urltogo=false, $logfile='') {
function auth_saml_error($err, $urltogo=false, $logfile='') {
global $CFG, $PAGE, $OUTPUT;

if(!isset($CFG->debugdisplay) || !$CFG->debugdisplay) {
Expand Down Expand Up @@ -32,15 +32,15 @@ function saml_error($err, $urltogo=false, $logfile='') {
echo $messages;
}
$msg = 'Moodle SAML module: '.$key.': '.$messages;
log_saml_error($msg, $logfile);
auth_saml_log_error($msg, $logfile);
}
else {
foreach($messages as $message) {
if($urltogo!=false && ($debug || $key == 'course_enrollment')) {
echo $message.'<br>';
}
$msg = 'Moodle SAML module: '.$key.': '.$message;
log_saml_error($msg, $logfile);
auth_saml_log_error($msg, $logfile);
}
}
echo '<br>';
Expand All @@ -51,7 +51,7 @@ function saml_error($err, $urltogo=false, $logfile='') {
echo $err;
}
$msg = 'Moodle SAML module: login: '.$err;
log_saml_error($msg, $logfile);
auth_saml_log_error($msg, $logfile);
}
if($urltogo!=false) {
echo '</div>';
Expand All @@ -64,12 +64,12 @@ function saml_error($err, $urltogo=false, $logfile='') {
}
}

function log_saml_error($msg, $logfile) {
function auth_saml_log_error($msg, $logfile) {
global $CFG;
// 0 - message is sent to PHP's system logger, using the Operating System's system logging mechanism or a file.
// 3 - message is appended to the file destination
$destination = '';
$error_log_type = 0;
$error_log_type = 0;
if(isset($logfile) && !empty($logfile)) {
if (substr($logfile, 0) == '/') {
$destination = $logfile;
Expand All @@ -78,12 +78,12 @@ function log_saml_error($msg, $logfile) {
$destination = $CFG->dataroot . '/' . $logfile;
}
$error_log_type = 3;
$msg = decorate_saml_log($msg);
$msg = auth_saml_decorate_log($msg);
}
error_log($msg, $error_log_type, $destination);
}


function decorate_saml_log($msg) {
function auth_saml_decorate_log($msg) {
return $msg = date('D M d H:i:s Y').' [client '.$_SERVER['REMOTE_ADDR'].'] [error] '.$msg."\r\n";
}
39 changes: 21 additions & 18 deletions auth/saml/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@
// we log in and register the attributes of user

try{
global $CFG;
// We read saml parameters from a config file instead from the database
// due we can not operate with the moodle database without load all
// moodle session issue.
if(!file_exists('saml_config.php')) {
if (file_exists('saml_config.php')) {
$contentfile = file_get_contents('saml_config.php');
} else {
throw(new Exception('SAML config params are not set.'));
}
$contentfile = file_get_contents('saml_config.php');

$saml_param = json_decode($contentfile);

if(!file_exists($saml_param->samllib.'/_autoload.php')) {
Expand Down Expand Up @@ -50,7 +53,7 @@
require_once('../../config.php');
require_once('error.php');

global $CFG, $err, $PAGE, $OUTPUT;
global $err, $PAGE, $OUTPUT;
$PAGE->set_url('/auth/saml/index.php');
$PAGE->set_context(CONTEXT_SYSTEM::instance());

Expand All @@ -61,16 +64,16 @@
}

$err['login'] = $e->getMessage();
log_saml_error('Moodle SAML module:'. $err['login'], $pluginconfig->samllogfile);;
saml_error($err['login'], $urltogo, $pluginconfig->samllogfile);
auth_saml_log_error('Moodle SAML module:'. $err['login'], $pluginconfig->samllogfile);;
auth_saml_error($err['login'], $urltogo, $pluginconfig->samllogfile);
}

// Now we close simpleSAMLphp session
session_write_close();

// We load all moodle config and libs
require_once('../../config.php');
require_once('error.php');
require_once('error.php');

global $CFG, $USER, $SAML_COURSE_INFO, $SESSION, $err, $DB, $PAGE;

Expand Down Expand Up @@ -98,7 +101,7 @@
$as->requireAuth();
} catch (Exception $e) {
$err['login'] = $e->getMessage();
saml_error($err['login'], $urltogo, $pluginconfig->samllogfile);
auth_saml_error($err['login'], $urltogo, $pluginconfig->samllogfile);
}
} else {
// Valid session. Register or update user in Moodle, log him on, and redirect to Moodle front
Expand All @@ -111,11 +114,11 @@
}

// We require the plugin to know that we are now doing a saml login in hook puser_login
$GLOBALS['saml_login'] = TRUE;
$SESSION->auth_saml_login = TRUE;

// Make variables accessible to saml->get_userinfo. Information will be
// requested from authenticate_user_login -> create_user_record / update_user_record
$GLOBALS['saml_login_attributes'] = $saml_attributes;
$SESSION->auth_saml_login_attributes = $saml_attributes;

if (isset($pluginconfig->username) && $pluginconfig->username != '') {
$username_field = $pluginconfig->username;
Expand All @@ -125,7 +128,7 @@

if(!isset($saml_attributes[$username_field])) {
$err['login'] = get_string("auth_saml_username_not_found", "auth_saml", $username_field);
saml_error($err['login'], '?logout', $pluginconfig->samllogfile);
auth_saml_error($err['login'], '?logout', $pluginconfig->samllogfile);
}
$username = $saml_attributes[$username_field][0];
$username = trim(core_text::strtolower($username));
Expand All @@ -134,9 +137,9 @@
if($pluginconfig->supportcourses != 'nosupport' && isset($pluginconfig->samlcourses)) {
if(!isset($saml_attributes[$pluginconfig->samlcourses])) {
$err['login'] = get_string("auth_saml_courses_not_found", "auth_saml", $pluginconfig->samlcourses);
saml_error($err['login'], '?logout', $pluginconfig->samllogfile);
auth_saml_error($err['login'], '?logout', $pluginconfig->samllogfile);
}
$saml_courses = $saml_attributes[$pluginconfig->samlcourses];
$saml_courses = $saml_attributes[$pluginconfig->samlcourses];
}

// Obtain the course_mapping. Now $USER->mapped_courses have the mapped courses and $USER->mapped_roles the roles
Expand Down Expand Up @@ -173,39 +176,39 @@

if (!$authorize_user) {
$err['login'] = "<p>" . $authorize_error . "</p>";
saml_error($err, '?logout', $pluginconfig->samllogfile);
auth_saml_error($err, '?logout', $pluginconfig->samllogfile);
}

// Just passes time as a password. User will never log in directly to moodle with this password anyway or so we hope?
$user = authenticate_user_login($username, time());
if ($user === false) {
$err['login'] = get_string("auth_saml_error_authentication_process", "auth_saml", $username);
saml_error($err['login'], '?logout', $pluginconfig->samllogfile);
auth_saml_error($err['login'], '?logout', $pluginconfig->samllogfile);
}

// Complete the user login sequence
$user = get_complete_user_data('id', $user->id);
if ($user === false) {
$err['login'] = get_string("auth_saml_error_complete_user_data", "auth_saml", $username);
saml_error($err['login'], '?logout', $pluginconfig->samllogfile);
auth_saml_error($err['login'], '?logout', $pluginconfig->samllogfile);
}

$USER = complete_user_login($user);

if (function_exists('saml_hook_post_user_created')) {
saml_hook_post_user_created($USER);
}

if (isset($SESSION->wantsurl) && !empty($SESSION->wantsurl)) {
$urltogo = $SESSION->wantsurl;
$urltogo = $SESSION->wantsurl;
}

$USER->loggedin = true;
$USER->site = $CFG->wwwroot;
set_moodle_cookie($USER->username);

if(isset($err) && !empty($err)) {
saml_error($err, $urltogo, $pluginconfig->samllogfile);
auth_saml_error($err, $urltogo, $pluginconfig->samllogfile);
}
redirect($urltogo);
}
2 changes: 2 additions & 0 deletions auth/saml/lang/en/auth_saml.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

$string['auth_saml_loginusing'] = 'Login here using your username and password';

$string['auth_samltitle'] = 'SAML Authentication';
$string['auth_samldescription'] = 'SSO Authentication using SimpleSAML';

Expand Down
Loading

0 comments on commit ef3ad62

Please sign in to comment.