Problem/Motivation
I've just started investigating samlauth and have been trying out the option to map a SAML user to an existing local Drupal user. I was getting confusing results and on investigating it looks to me like the code in the samlauth_acs function that deals with mapping users actually uses the wrong configuration variables.
Steps to reproduce
The config form has fields related to mapping users like this:
$form['user_info']['samlauth_map_users'] = array(
'#type' => 'checkbox',
'#title' => t('Attempt to map SAML users to existing local users?'),
'#description' => t('If this option is enabled and a SAML authentication response is received for a user that already exists locally, and the user\'s email matches the configured attribute, the SAML user will be mapped to the local user and then logged in.'),
'#default_value' => variable_get('samlauth_map_users', FALSE),
);
$form['user_info']['samlauth_map_users_email'] = array(
'#type' => 'textfield',
'#title' => t('Email attribute (for mapping)'),
'#description' => t('This attribute will be used for mapping SAML users to local Drupal users.'),
'#default_value' => variable_get('samlauth_map_users_email', FALSE),
'#states' => array(
'invisible' => array(
':input[name="samlauth_map_users"]' => array('checked' => FALSE),
),
),
);
and the samlauth_acs function code to map to an existing user looks like this:
else {
$mail_attribute = variable_get('samlauth_user_mail_attribute', 'email');
if (variable_get('samlauth_map_users_email', FALSE) && $account = user_load_by_mail($saml_data[$mail_attribute])) {
samlauth_associate_saml_id_with_account($unique_id, $account);
}
elseif (variable_get('samlauth_create_users', FALSE)) {
$account = samlauth_create_user_from_saml_data($saml_data);
}
else {
throw new Exception('No existing user account matches the SAML ID provided. This authentication service is not configured to create new accounts.');
}
}
Proposed resolution
I think the code should look like this:
else {
$mail_attribute = variable_get('samlauth_map_users_email', 'email');
if (variable_get('samlauth_map_users', FALSE) && $account = user_load_by_mail($saml_data[$mail_attribute])) {
samlauth_associate_saml_id_with_account($unique_id, $account);
}
elseif (variable_get('samlauth_create_users', FALSE)) {
$account = samlauth_create_user_from_saml_data($saml_data);
}
else {
throw new Exception('No existing user account matches the SAML ID provided. This authentication service is not configured to create new accounts.');
}
}
i.e.
$ diff old.txt new.txt
2,3c2,3
< $mail_attribute = variable_get('samlauth_user_mail_attribute', 'email');
< if (variable_get('samlauth_map_users_email', FALSE) && $account = user_load_by_mail($saml_data[$mail_attribute])) {
---
> $mail_attribute = variable_get('samlauth_map_users_email', 'email');
> if (variable_get('samlauth_map_users', FALSE) && $account = user_load_by_mail($saml_data[$mail_attribute])) {
Comments
Comment #2
andrewmk commentedComment #3
bkdrupal commentedNeed to update the mapping functionality like below, because $unique_id is the value which was came from other system (Eg email/username etc..)
-- samlauth_associate_saml_id_with_account($unique_id, $account);
++ samlauth_associate_saml_id_with_account($account->uid, $account);
Comment #5
roderikThank you for tracing that. I fixed it in a different way: change the UI to conform to reality. That is: removing the 'samlauth_map_users' option from the UI, and using 'samlauth_map_users_email' as a boolean from now on.
This should have no consequences for unpatched installations, and if you patched your installation according to the above change, this should only have consequences if your samlauth_map_users_email and samlauth_user_mail_attribute variables contain different values.
I myself cannot see a use for having different values for samlauth_map_users_email and samlauth_user_mail_attribute variables and was confused by it. This functionality was present in 8.x-1.x, but I removed it in the 8.x-2.x version so that 'mapping' and 'creation' used the same e-mail value.
Now I see that the 7.x-1.x backport (from 8.x-1.x) didn't actually backport the 8.x-1.x functionality by accident, but is more in line with current 8.x behavior... which I'm happy with.