Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion classes/auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,8 @@ public function loginpage_idp_list($wantsurl) {

// Moodle Workplace - Check IdP's tenant availability.
// Check if function exists required for Totara 12 compatibility.
if (class_exists(\tool_tenant\local\auth\saml2\manager::class) && !component_class_callback('\tool_tenant\local\auth\saml2\manager',
if (class_exists(\tool_tenant\local\auth\saml2\manager::class)
&& !component_class_callback('\tool_tenant\local\auth\saml2\manager',
'issuer_available', [$idp->md5entityid], true)) {
continue;
}
Expand Down
2 changes: 0 additions & 2 deletions classes/testing/generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@

namespace auth_saml2\testing;

defined('MOODLE_INTERNAL') || die();

use stdClass;
use coding_exception;

Expand Down
2 changes: 0 additions & 2 deletions classes/testing/tests_generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@

namespace auth_saml2\testing;

defined('MOODLE_INTERNAL') || die();

/**
* Methods common to Moodle and Totara tests generators
*
Expand Down
12 changes: 9 additions & 3 deletions config/authsources.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,14 @@
$attr = substr($attr, 0, -2);
$attributesrequired[] = $attr;
}

$attributes[] = $attr;

// If the line has a space in it then first part is FriendlyName.
if (strpos($attr, ' ') !== false) {
$parts = explode(' ', $attr, 2);
$attributes[$parts[0]] = $parts[1];
} else {
$attributes[] = $attr;
}
}

$config[$saml2auth->spname] = [
Expand All @@ -80,11 +86,11 @@
'redirect.sign' => true,
'signature.algorithm' => $saml2auth->config->signaturealgorithm,
'WantAssertionsSigned' => $saml2auth->config->wantassertionssigned == 1,

'name' => [
$CFG->lang => $SITE->fullname,
],
'attributes' => $attributes,
'attributes.NameFormat' => $saml2auth->config->requestedattributesformat,
'attributes.required' => $attributesrequired,
];

Expand Down
10 changes: 9 additions & 1 deletion lang/en/auth_saml2.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
$string['commonname'] = 'Common Name';
$string['countryname'] = 'Country';
$string['debug'] = 'Debugging';
$string['debugsettings'] = 'Debug and logging';
$string['debug_help'] = '<p>This adds extra debugging to the normal moodle log | <a href=\'{$a}\'>View SSP config</a></p>';
$string['duallogin'] = 'Dual login';
$string['duallogin_help'] = '
Expand Down Expand Up @@ -92,8 +93,10 @@
$string['flagmessage_default'] = 'You are logged in to your identity provider however, this account has limited access to Moodle, please contact your administrator for more details.';
$string['flagresponsetype'] = 'Account blocking response type';
$string['flagresponsetype_help'] = 'If access is blocked based on configured group restrictions, how should Moodle respond?';
$string['groupsettings'] = 'Group rules and blocking';
$string['idpattr_help'] = 'Which IdP attribute should be matched against a Moodle user field?';
$string['idpattr'] = 'Mapping IdP';
$string['idpsettings'] = 'IdP setup and metadata';
$string['idpmetadata_badurl'] = 'Invalid metadata at {$a}';
$string['idpmetadata_help'] = 'To use multiple IdPs enter each public metadata url on a new line.<br/>To override a name, place text before the http. eg. "Forced IdP Name http://ssp.local/simplesaml/saml2/idp/metadata.php"';
$string['idpmetadata'] = 'IdP metadata xml OR public xml URL';
Expand All @@ -106,6 +109,7 @@
$string['idpname_help'] = 'eg myUNI - this is detected from the metadata and will show on the dual login page (if enabled)';
$string['idpname'] = 'IdP label override';
$string['localityname'] = 'Locality';
$string['logoutsettings'] = 'Logout settings';
$string['logdirdefault'] = '/tmp/';
$string['logdir_help'] = 'The log directory SSPHP will write to, the file will be named simplesamlphp.log';
$string['logdir'] = 'Log Directory';
Expand All @@ -118,6 +122,7 @@
$string['wantassertionssigned_help'] = 'Whether assertions received by this SP must be signed';
$string['assertionsconsumerservices'] = 'Assertions consumer services';
$string['assertionsconsumerservices_help'] = 'List of bindings the SP should support';
$string['spsettings'] = 'Service Provider details';
$string['spentityid'] = 'Entity ID';
$string['spentityid_help'] = 'Override the Entity Id of the Service Provider. In most cases leave blank and a good default will be used instead.';
$string['allowcreate'] = 'Allow create';
Expand Down Expand Up @@ -163,7 +168,9 @@
$string['regenerateheading'] = 'Regenerate Private Key and Certificate';
$string['regenerate_submit'] = 'Regenerate';
$string['requestedattributes'] = 'Requested attributes';
$string['requestedattributes_help'] = 'Some IdP\'s need the SP to declare which attributes will be requested or are required. Add each attribute on a new line and these will be present in the SP metadata under the <code>AttributeConsumingService</code> tag. If you want a field to be required put a space and then * after that line. {$a->example}';
$string['requestedattributes_help'] = 'Some IdP\'s need the SP to declare which attributes will be requested or are required. Add each attribute on a new line and these will be present in the SP metadata under the <code>AttributeConsumingService</code> tag. If you want a field to be required put a space and then * after that line. If you prefix a line with a word and space the word will be used as the FriendlyName. {$a->example}';
$string['requestedattributesformat'] = 'Requested attributes format';
$string['requestedattributesformat_help'] = 'When requesting atttributes what format are they defined in? Ignored if no attributes requested.';
$string['rememberidp'] = 'Remember login service';
$string['required'] = 'This field is required';
$string['requireint'] = 'This field is required and needs to be a positive integer';
Expand Down Expand Up @@ -195,6 +202,7 @@
<p>Exact: match is case sensitive (default).</p>
<p>Lower case: applies lower case to the IdP attribute before matching.</p>
<p>Case insensitive: ignore case when matching.</p>';
$string['usersettings'] = 'User matching and creation';
$string['wrongauth'] = 'You have logged in successfully as \'{$a}\' but are not authorized to access Moodle.';
$string['auth_data_mapping'] = 'Data mapping';
$string['auth_fieldlockfield'] = 'Lock value ({$a})';
Expand Down
198 changes: 121 additions & 77 deletions settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,27 @@
if ($ADMIN->fulltree) {
require_once($CFG->dirroot.'/auth/saml2/locallib.php');

$sections = [
'idpsettings',
'spsettings',
'usersettings',
'logoutsettings',
'groupsettings',
'debugsettings',
];
$toc = '<ol>';
foreach ($sections as $key => $section) {
$toc .= '<li>';
$toc .= '<a href="#:~:text=' . ($key + 1) . '. ' . get_string($section, 'auth_saml2');
$toc .= '">';
$toc .= get_string($section, 'auth_saml2');
$toc .= '</a>';
}
$toc .= '</ol>';
$settings->add(new admin_setting_heading('samltoc', 'SAML settings', $toc));

// -----------------------------------------------------------------------------------------------------
$settings->add(new admin_setting_heading('samlidp', '1. ' . get_string('idpsettings', 'auth_saml2'), ''));
$yesno = array(
new lang_string('no'),
new lang_string('yes'),
Expand Down Expand Up @@ -80,45 +101,21 @@
get_string('idpmetadatarefresh_help', 'auth_saml2'),
1, $yesno));

// Debugging.
// Multi IdP display type.
$multiidpdisplayoptions = [
saml2_settings::OPTION_MULTI_IDP_DISPLAY_DROPDOWN => get_string('multiidpdropdown', 'auth_saml2'),
saml2_settings::OPTION_MULTI_IDP_DISPLAY_BUTTONS => get_string('multiidpbuttons', 'auth_saml2')
];
$settings->add(new admin_setting_configselect(
'auth_saml2/debug',
get_string('debug', 'auth_saml2'),
get_string('debug_help', 'auth_saml2', $CFG->wwwroot . '/auth/saml2/debug.php'),
0, $yesno));
'auth_saml2/multiidpdisplay',
get_string('multiidpdisplay', 'auth_saml2'),
get_string('multiidpdisplay_help', 'auth_saml2'),
saml2_settings::OPTION_MULTI_IDP_DISPLAY_DROPDOWN,
$multiidpdisplayoptions));

// Logging.
$settings->add(new admin_setting_configselect(
'auth_saml2/logtofile',
get_string('logtofile', 'auth_saml2'),
get_string('logtofile_help', 'auth_saml2'),
0, $yesno));
$settings->add(new admin_setting_configtext(
'auth_saml2/logdir',
get_string('logdir', 'auth_saml2'),
get_string('logdir_help', 'auth_saml2'),
get_string('logdirdefault', 'auth_saml2'),
PARAM_TEXT));

// See section 8.3 from http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf for more information.
$nameidlist = [
'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified',
'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
'urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName',
'urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName',
'urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos',
'urn:oasis:names:tc:SAML:2.0:nameid-format:entity',
'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
'urn:oasis:names:tc:SAML:2.0:nameid-format:transient',
];
$nameidpolicy = new admin_setting_configselect(
'auth_saml2/nameidpolicy',
get_string('nameidpolicy', 'auth_saml2'),
get_string('nameidpolicy_help', 'auth_saml2'),
'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified',
array_combine($nameidlist, $nameidlist));
$nameidpolicy->set_updatedcallback('auth_saml2_update_sp_metadata');
$settings->add($nameidpolicy);
// -----------------------------------------------------------------------------------------------------
$settings->add(new admin_setting_heading('samluser', '2. ' . get_string('spsettings', 'auth_saml2'), ''));

// Add NameID as attribute.
$settings->add(new admin_setting_configselect(
Expand Down Expand Up @@ -225,6 +222,30 @@
ssl_algorithms::get_default_saml_signature_algorithm(),
ssl_algorithms::get_valid_saml_signature_algorithms()));

// -----------------------------------------------------------------------------------------------------
$settings->add(new admin_setting_heading('samlusersettings', '3. ' . get_string('usersettings', 'auth_saml2'), ''));

// See section 8.3 from http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf for more information.
$nameidlist = [
'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified',
'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
'urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName',
'urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName',
'urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos',
'urn:oasis:names:tc:SAML:2.0:nameid-format:entity',
'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
'urn:oasis:names:tc:SAML:2.0:nameid-format:transient',
];
$nameidpolicy = new admin_setting_configselect(
'auth_saml2/nameidpolicy',
get_string('nameidpolicy', 'auth_saml2'),
get_string('nameidpolicy_help', 'auth_saml2'),
'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified',
array_combine($nameidlist, $nameidlist));
$nameidpolicy->set_updatedcallback('auth_saml2_update_sp_metadata');
$settings->add($nameidpolicy);


// Dual Login.
$dualloginoptions = [
saml2_settings::OPTION_DUAL_LOGIN_NO => get_string('no'),
Expand Down Expand Up @@ -301,31 +322,33 @@
saml2_settings::OPTION_TOLOWER_EXACT,
$toloweroptions));

// Requested Attributes.
$settings->add(new admin_setting_configtextarea(
'auth_saml2/requestedattributes',
get_string('requestedattributes', 'auth_saml2'),
get_string('requestedattributes_help', 'auth_saml2', ['example' => "<pre>
urn:mace:dir:attribute-def:eduPersonPrincipalName
urn:mace:dir:attribute-def:mail *</pre>"]),
'',
PARAM_TEXT));

// Autocreate Users.
$settings->add(new admin_setting_configselect(
'auth_saml2/autocreate',
get_string('autocreate', 'auth_saml2'),
get_string('autocreate_help', 'auth_saml2'),
0, $yesno));

// Group access rules.
// Requested Attributes.
$settings->add(new admin_setting_configtextarea(
'auth_saml2/grouprules',
get_string('grouprules', 'auth_saml2'),
get_string('grouprules_help', 'auth_saml2'),
'auth_saml2/requestedattributes',
get_string('requestedattributes', 'auth_saml2'),
get_string('requestedattributes_help', 'auth_saml2', ['example' => "<pre>
eduPersonPrincipalName urn:mace:dir:attribute-def:eduPersonPrincipalName
urn:mace:dir:attribute-def:mail *</pre>"]),
'',
PARAM_TEXT));

// Formats for request attributes.
$settings->add(new admin_setting_configtext(
'auth_saml2/requestedattributesformat',
get_string('requestedattributesformat', 'auth_saml2'),
get_string('requestedattributesformat_help', 'auth_saml2'),
'urn:oasis:names:tc:SAML:2.0:attrname-format:uri'));

// -----------------------------------------------------------------------------------------------------
$settings->add(new admin_setting_heading('samllogoutsettings', '4. ' . get_string('logoutsettings', 'auth_saml2'), ''));

// Alternative Logout URL.
$settings->add(new admin_setting_configtext(
'auth_saml2/alterlogout',
Expand All @@ -334,18 +357,6 @@
'',
PARAM_URL));

// Multi IdP display type.
$multiidpdisplayoptions = [
saml2_settings::OPTION_MULTI_IDP_DISPLAY_DROPDOWN => get_string('multiidpdropdown', 'auth_saml2'),
saml2_settings::OPTION_MULTI_IDP_DISPLAY_BUTTONS => get_string('multiidpbuttons', 'auth_saml2')
];
$settings->add(new admin_setting_configselect(
'auth_saml2/multiidpdisplay',
get_string('multiidpdisplay', 'auth_saml2'),
get_string('multiidpdisplay_help', 'auth_saml2'),
saml2_settings::OPTION_MULTI_IDP_DISPLAY_DROPDOWN,
$multiidpdisplayoptions));

// Attempt Single Sign out.
$settings->add(new admin_setting_configselect(
'auth_saml2/attemptsignout',
Expand All @@ -354,24 +365,19 @@
1,
$yesno));

// SAMLPHP version.
$authplugin = get_auth_plugin('saml2');
$settings->add(new setting_textonly(
'auth_saml2/sspversion',
get_string('sspversion', 'auth_saml2'),
$authplugin->get_ssp_version()
));


// Display locking / mapping of profile fields.
$help = get_string('auth_updatelocal_expl', 'auth');
$help .= get_string('auth_fieldlock_expl', 'auth');
$help .= get_string('auth_updateremote_expl', 'auth');

// -----------------------------------------------------------------------------------------------------
// User block and redirect feature setting section.
$settings->add(new admin_setting_heading('auth_saml2/blockredirectheading', get_string('blockredirectheading', 'auth_saml2'),
$settings->add(new admin_setting_heading('auth_saml2/groupsettings', '5. ' . get_string('groupsettings', 'auth_saml2'),
new lang_string('auth_saml2blockredirectdescription', 'auth_saml2')));

// Group access rules.
$settings->add(new admin_setting_configtextarea(
'auth_saml2/grouprules',
get_string('grouprules', 'auth_saml2'),
get_string('grouprules_help', 'auth_saml2'),
'',
PARAM_TEXT));

// Flagged login response options.
$flaggedloginresponseoptions = [
saml2_settings::OPTION_FLAGGED_LOGIN_MESSAGE => get_string('flaggedresponsetypemessage', 'auth_saml2'),
Expand Down Expand Up @@ -405,6 +411,44 @@
50,
3));

// -----------------------------------------------------------------------------------------------------
$settings->add(new admin_setting_heading('samldebugsettings', '6. ' . get_string('debugsettings', 'auth_saml2'), ''));

// Debugging.
$settings->add(new admin_setting_configselect(
'auth_saml2/debug',
get_string('debug', 'auth_saml2'),
get_string('debug_help', 'auth_saml2', $CFG->wwwroot . '/auth/saml2/debug.php'),
0, $yesno));

// Logging.
$settings->add(new admin_setting_configselect(
'auth_saml2/logtofile',
get_string('logtofile', 'auth_saml2'),
get_string('logtofile_help', 'auth_saml2'),
0, $yesno));
$settings->add(new admin_setting_configtext(
'auth_saml2/logdir',
get_string('logdir', 'auth_saml2'),
get_string('logdir_help', 'auth_saml2'),
get_string('logdirdefault', 'auth_saml2'),
PARAM_TEXT));

// SAMLPHP version.
$authplugin = get_auth_plugin('saml2');
$settings->add(new setting_textonly(
'auth_saml2/sspversion',
get_string('sspversion', 'auth_saml2'),
$authplugin->get_ssp_version()
));

// -----------------------------------------------------------------------------------------------------

// Display locking / mapping of profile fields.
$help = get_string('auth_updatelocal_expl', 'auth');
$help .= get_string('auth_fieldlock_expl', 'auth');
$help .= get_string('auth_updateremote_expl', 'auth');

if (moodle_major_version() < '3.3') {
auth_saml2_display_auth_lock_options($settings, $authplugin->authtype, $authplugin->userfields, $help, true, true,
$authplugin->get_custom_user_profile_fields());
Expand Down
2 changes: 1 addition & 1 deletion tests/behat/account-blocking-admin.feature
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Feature: SAML2 Account blocking settings
Given the authentication plugin saml2 is enabled # auth_saml2
And I am an administrator # auth_saml2
When I navigate to "Plugins > Authentication > SAML2" in site administration
Then I should see "Account blocking actions"
Then I should see "Group rules and blocking"
And I should see "Redirect or display message to SAML2 logins based on configured group restrictions"

Scenario Outline: I can change the Account blocking response type options
Expand Down
4 changes: 2 additions & 2 deletions version.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@

defined('MOODLE_INTERNAL') || die();

$plugin->version = 2022090500; // The current plugin version (Date: YYYYMMDDXX).
$plugin->release = 2022090500; // Match release exactly to version.
$plugin->version = 2022090700; // The current plugin version (Date: YYYYMMDDXX).
$plugin->release = 2022090700; // Match release exactly to version.
$plugin->requires = 2017051509; // Requires PHP 7, 2017051509 = T12. M3.3
// Strictly we require either Moodle 3.5 OR
// we require Totara 3.3, but the version number
Expand Down