sql = "u.session = ?";
$user_select_sql->parameters = ["s",$session_hash];
if (validate_user($user_select_sql, false) === false) {
debug("simplesaml: standard user login - invalid user session");
rs_setcookie('user', '', 0);
}
debug("simplesaml: standard user login - no action required");
return true;
}
if (!$simplesaml_allow_standard_login) {
global $show_anonymous_login_panel;
$show_anonymous_login_panel = false;
}
// If not blocking site completely and allowing standard logins but not on login page, do nothing and return
if (!$simplesaml_site_block && $simplesaml_allow_standard_login) {
debug("simplesaml: standard user login - no action required");
return true;
}
// Check for exclusions
$k = getval('k', '');
$resource = getval('ref', '');
$search = getval('search', '');
$collection_from_search = str_replace('!collection', '', $search);
$collection_add = getval('collection_add', '');
$c = getval('c', '');
$parent = getval('parent', '');
$collection_from_search = is_numeric($collection_from_search) ? (int)$collection_from_search : null;
$collection_add = is_numeric($collection_add) ? (int)$collection_add : null;
$c = is_numeric($c) ? (int)$c : null;
$parent = is_numeric($parent) ? (int) $parent : null;
$resource = is_numeric($resource) ? (int)$resource : null;
if ($simplesaml_allow_public_shares && '' !== $k) {
// Hard to determine at this stage what we consider a collection/ resource ID so we
// use the most general ones
if ($collection_from_search && check_access_key_collection($collection_from_search, $k)) {
return true;
}
if ($collection_add && check_access_key_collection($collection_add, $k)) {
return true;
}
if ($c && check_access_key_collection($c, $k)) {
return true;
}
if ($resource && check_access_key($resource, $k)) {
return true;
}
// External sharing of a featured collection category
if ($parent && check_access_key_collection($parent, $k)) {
return true;
}
}
$url = str_replace("\\", "/", $_SERVER["PHP_SELF"]);
if ($simplesaml_allow_public_shares) {
// Allow redirect for password protected external shares
$simplesaml_allowedpaths[] = '/pages/share_access.php';
}
foreach ($simplesaml_allowedpaths as $simplesaml_allowedpath) {
if ('' == trim($simplesaml_allowedpath)) {
continue;
}
$samlexempturl = strpos($url, $simplesaml_allowedpath);
if ($samlexempturl !== false && $samlexempturl == 0) {
return true;
}
}
simplesaml_authenticate();
return true;
}
function HookSimplesamlAllProvideusercredentials()
{
if (!simplesaml_php_check()) {
return false;
}
global $pagename, $simplesaml_allow_standard_login, $simplesaml_prefer_standard_login, $baseurl, $path,
$default_res_types, $scramble_key, $simplesaml_username_suffix, $simplesaml_username_attribute,
$simplesaml_fullname_attribute, $simplesaml_email_attribute, $simplesaml_group_attribute,
$simplesaml_fallback_group, $simplesaml_groupmap, $user_select_sql, $session_hash,
$simplesaml_fullname_separator,$simplesaml_username_separator, $simplesaml_custom_attributes,$lang,
$simplesaml_login, $simplesaml_site_block, $anonymous_login,$allow_password_change,
$simplesaml_create_new_match_email, $simplesaml_allow_duplicate_email, $simplesaml_multiple_email_notify,
$simplesaml_authorisation_claim_name, $simplesaml_authorisation_claim_value, $usercredentialsprovided;
// Don't authenticate if this hook has already been handled by another higher priority plugin
if (isset($usercredentialsprovided) && $usercredentialsprovided) {
return false;
}
// Allow anonymous logins outside SSO if simplesaml is not configured to block access to site.
// NOTE: if anonymous_login is set to an invalid user, then use SSO otherwise it goes in an indefinite loop
if (
!$simplesaml_site_block
&& isset($anonymous_login)
&& trim($anonymous_login) !== ''
&& getval("usesso", "") == ""
) {
debug("simplesaml: checking for anonymous user");
$anonymous_login_found = ps_value(
"SELECT username AS `value` FROM user WHERE username = ?",
array("s",$anonymous_login),
''
);
// If anonymous_login is not set to a real username then use SSO to authenticate
if ($anonymous_login_found == '') {
simplesaml_authenticate();
}
if (!simplesaml_is_authenticated()) {
return true;
} elseif (!$simplesaml_login) {
global $show_anonymous_login_panel;
$show_anonymous_login_panel = false;
}
}
// If user is logged in or if SAML is not being used to login to ResourceSpace (just as a simple barrier,
// usually with anonymous access configured) then use standard authentication if available
if ($simplesaml_site_block && !simplesaml_is_authenticated()) {
debug("simplesaml: site block enabled, performing SAML authentication");
simplesaml_authenticate();
}
if (
(isset($_COOKIE['user']) && $simplesaml_allow_standard_login)
|| (!$simplesaml_login && simplesaml_is_authenticated())
) {
return true;
}
// Return false if not already authenticated and local login option is preferred
if (
!simplesaml_is_authenticated()
&& $simplesaml_allow_standard_login
&& $simplesaml_prefer_standard_login
&& getval("usesso", "") == ""
) {
return false;
}
if (!simplesaml_is_authenticated()) {
if ($pagename == "done" && !isset($_COOKIE["SimpleSAMLAuthToken"])) {
// Don't attempt to authenticate when on done.php if user is not already authenticated
return false;
} elseif (getval("ajax", "") != "") {
// Ajax loads can't be redirected. Need a full reload if session has timed out
$url_alt = isset($_SERVER["HTTP_HOST"]) ? $_SERVER["REQUEST_SCHEME"] . "://" . $_SERVER["HTTP_HOST"] . ":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"] : $baseurl;
$reload_url = isset($_SERVER["HTTP_REFERER"]) ? $_SERVER["HTTP_REFERER"] : $url_alt;
debug("simplesaml: ajax request - reloading page " . $reload_url);
?>
0) {
$username_attributes = explode(",", $simplesaml_username_attribute);
$username_parts = [];
foreach ($username_attributes as $username_attribute) {
if (isset($attributes[$username_attribute][0])) {
if (is_object($attributes[$username_attribute][0])) {
$username_parts[] = $attributes[$username_attribute][0]->getValue();
} elseif (is_string($attributes[$username_attribute][0])) {
$username_parts[] = $attributes[$username_attribute][0];
}
}
}
if (count($username_parts) > 0) {
$username = implode($simplesaml_username_separator, $username_parts);
}
}
if ($username == '') {
debug("simplesaml: WARNING: no username found, attempting to use NameID");
// Attempt to fall back to NameID, truncated as necessary
$username = simplesaml_getauthdata("saml:sp:NameID");
}
if ($username == '') {
// no username, can't continue
debug("simplesaml: WARNING: no username found, aborting");
return false;
}
// truncate if necessary
if (strlen($username) > 50) {
$username = mb_substr($username, 0, 15) . "_" . md5($username);
}
$username = $username . $simplesaml_username_suffix;
// If local authorisation based on assertion/ claim is needed, check now and make sure we don't process any further!
if (
(trim($simplesaml_authorisation_claim_name) != '' && trim($simplesaml_authorisation_claim_value) != '')
&& (
!array_key_exists($simplesaml_authorisation_claim_name, $attributes)
|| !in_array($simplesaml_authorisation_claim_value, $attributes[$simplesaml_authorisation_claim_name])
)
) {
debug("simplesaml: WARNING: Unauthorised login attempt recorded for username '{$username}'!");
?>
0) {
$userid = $currentuser[0]["ref"];
if ($legacy_username_used) {
ps_query("UPDATE user SET username = ? WHERE ref = ?", array("s",$username,"i",$userid));
}
// Update hash if not logged on in last day
$lastactive = strtotime((string)$currentuser[0]["last_active"]);
if ($lastactive < date(time() - (60 * 60 * 24))) {
$update_hash = true;
}
}
debug("simplesaml - got user details username=" . $username . ", email: " . (isset($email) ? $email : "(not received)"));
if (!isset($email)) {
// No email - may be a test account?
$email = "";
}
// figure out group
$group = $simplesaml_fallback_group;
$currentpriority = 0;
if (count($simplesaml_groupmap) > 0) {
for ($i = 0; $i < count($simplesaml_groupmap); $i++) {
for ($g = 0; $g < count($groups); $g++) {
if (
($groups[$g] == $simplesaml_groupmap[$i]['samlgroup'])
&& is_numeric($simplesaml_groupmap[$i]['rsgroup'])
&& $simplesaml_groupmap[$i]['priority'] > $currentpriority
) {
$group = $simplesaml_groupmap[$i]['rsgroup'];
$currentpriority = $simplesaml_groupmap[$i]['priority'];
debug("simplesaml - found mapping for SAML group: " . $groups[$g] . ", group #" . $simplesaml_groupmap[$i]['rsgroup'] . ". priority :" . $simplesaml_groupmap[$i]['priority']);
}
}
}
}
debug("simplesaml - using RS group #" . $group);
// If custom attributes need to be recorded against a user record, do it now
$custom_attributes = array();
if ('' != $simplesaml_custom_attributes) {
$search_custom_attributes = explode(',', $simplesaml_custom_attributes);
foreach ($attributes as $attribute => $attribute_value) {
if (!in_array($attribute, $search_custom_attributes)) {
continue;
}
// For now, we only allow one value per attribute
$custom_attributes[$attribute] = $attribute_value[0];
}
}
if ($userid <= 0) {
// User authenticated, but does not exist
// First see if there is a matching account
$email_matches = ps_query("SELECT ref, username, fullname, origin FROM user WHERE email=?", array("s",$email));
if (count($email_matches) > 0 && trim($email) != "") {
if (count($email_matches) == 1 && $simplesaml_create_new_match_email) {
// We want adopt this matching account - update the username and details to match the new login credentials
debug("simplesaml - user authenticated with matching email for existing user . " . $email . ", updating user account '" . $email_matches[0]["username"] . "' (id #" . $email_matches[0]["ref"] . ") to new username " . $username);
$userid = $email_matches[0]["ref"];
$origin = $email_matches[0]["origin"];
$comment = $lang["simplesaml_usermatchcomment"];
$update_hash = true;
} else {
if (!$simplesaml_allow_duplicate_email) {
if (filter_var($simplesaml_multiple_email_notify, FILTER_VALIDATE_EMAIL) && getval("usesso", "") != "") {
// Already account(s) with this email address, notify the administrator (provided it is an actual attempt to pevent unnecessary duplicates)
simplesaml_duplicate_notify($username, $group, $email, $email_matches, $userid);
}
// We are blocking accounts with the same email
if ($simplesaml_allow_standard_login) {
?>
0) {
global $simplesaml_update_group, $session_autologout;
// Update user info only for items which have changed.
$update_user_info_sql = array();
$update_user_info_params = array();
if ($currentuser[0]['origin'] !== 'simplesaml') {
$update_user_info_sql[] = 'origin = ?';
$update_user_info_params[] = 's';
$update_user_info_params[] = 'simplesaml';
}
if ($currentuser[0]['username'] !== $username) {
$update_user_info_sql[] = 'username = ?';
$update_user_info_params[] = 's';
$update_user_info_params[] = $username;
}
if ($update_hash) {
$password_hash = rs_password_hash('RSSAML' . generateSecureKey(64) . $username);
$update_user_info_sql[] = 'password = ?';
$update_user_info_params[] = 's';
$update_user_info_params[] = $password_hash;
}
if ($currentuser[0]['fullname'] !== $displayname) {
$update_user_info_sql[] = 'fullname = ?';
$update_user_info_params[] = 's';
$update_user_info_params[] = $displayname;
}
if (isset($email) && $email != "" && $currentuser[0]['email'] !== $email) {
// Only set email if provided. Allows accounts without an email address to have one set by the admin without it getting overwritten
$update_user_info_sql[] = 'email = ?';
$update_user_info_params[] = 's';
$update_user_info_params[] = $email;
}
if (isset($comment) && $currentuser[0]['comments'] !== $comment) {
$update_user_info_sql[] = 'comments = concat(comments, ?)';
$update_user_info_params[] = 's';
$update_user_info_params[] = "\n" . date("Y-m-d") . " " . $comment;
log_activity($comment, LOG_CODE_UNSPECIFIED, 'simplesaml', 'user', 'origin', $userid, null, (isset($origin) ? $origin : null), $userid);
}
if ($simplesaml_update_group || (isset($currentuser[0]["usergroup"]) && $currentuser[0]["usergroup"] == "")) {
$update_user_info_sql[] = 'usergroup = ?';
$update_user_info_params[] = 'i';
$update_user_info_params[] = $group;
}
if (0 < count($custom_attributes) && $currentuser[0]['simplesaml_custom_attributes'] !== json_encode($custom_attributes)) {
$custom_attributes = json_encode($custom_attributes);
$update_user_info_sql[] = 'simplesaml_custom_attributes = ?';
$update_user_info_params[] = 's';
$update_user_info_params[] = $custom_attributes;
}
if (count($update_user_info_sql) > 0) {
$sql = 'UPDATE user SET ';
$sql .= implode(', ', $update_user_info_sql);
$sql .= " WHERE ref = ?";
$update_user_info_params[] = 'i';
$update_user_info_params[] = $userid;
ps_query($sql, $update_user_info_params);
unset($GLOBALS['saml_current_user_cache'][$username]);
}
$user_select_sql = new PreparedStatementQuery();
$user_select_sql->sql = "u.username = ?";
$user_select_sql->parameters = ["s",$username];
$allow_password_change = false;
$session_autologout = false;
return true;
}
return false;
}
function HookSimplesamlAllLoginformlink()
{
// Add a link to login.php, as this page may still be seen if $simplesaml_allow_standard_login is set to true
global $baseurl, $lang, $simplesaml_login;
if (!simplesaml_php_check() || !$simplesaml_login) {
return false;
}
// Include URL redirect for RelayState
$requested = parse_url(getval("url", ""));
$relpath = trim($requested["path"] ?? "/");
if (file_exists(dirname(__DIR__, 3) . str_replace("../", "", $relpath))) {
// Only add if this is a valid file
parse_str($requested["query"] ?? "", $params);
if (!is_string($params[array_key_first($params)] ?? false)) {
unset($params);
}
}
if (!isset($params)) {
$relpath = "/";
}
$params['usesso'] = 'true';
?>