/** * Create a DemoStudent account which cannot log in manually, using the given username, * @param string demostudentusername username of account to create * @return object the user object */ function create_demostudent_account($demostudentusername) { global $USER, $DB, $passwordfiller; $demostudentuser = create_user_record($demostudentusername, ''); if ($demostudentuser) { $demostudentuser->firstname = "DemoStudent"; $demostudentuser->lastname = $USER->lastname; $demostudentuser->description = "DemoStudent account."; $demostudentuser->email = $USER->email; $demostudentuser->password = $passwordfiller; $DB->update_record('user', $demostudentuser); } return $demostudentuser; }
/** * Provides a hook into the login page. * * @param object &$frm Form object. * @param object &$user User object. */ public function loginpage_hook(&$frm, &$user) { global $DB; if (empty($frm)) { $frm = data_submitted(); } if (empty($frm)) { return true; } $autoappend = get_config('auth_oidc', 'autoappend'); if (empty($autoappend)) { // If we're not doing autoappend, just let things flow naturally. return true; } $username = $frm->username; $password = $frm->password; $auth = 'oidc'; $existinguser = $DB->get_record('user', ['username' => $username]); if (!empty($existinguser)) { // We don't want to prevent access to existing accounts. return true; } $username .= $autoappend; $success = $this->user_login($username, $password); if ($success !== true) { // No o365 user, continue normally. return false; } $existinguser = $DB->get_record('user', ['username' => $username]); if (!empty($existinguser)) { $user = $existinguser; return true; } // The user is authenticated but user creation may be disabled. if (!empty($CFG->authpreventaccountcreation)) { $failurereason = AUTH_LOGIN_UNAUTHORISED; // Trigger login failed event. $event = \core\event\user_login_failed::create(array('other' => array('username' => $username, 'reason' => $failurereason))); $event->trigger(); error_log('[client ' . getremoteaddr() . "] {$CFG->wwwroot} Unknown user, can not create new accounts: {$username} " . $_SERVER['HTTP_USER_AGENT']); return false; } $user = create_user_record($username, $password, $auth); return true; }
protected function process_turnitintool_courses($data) { global $CFG, $DB; $data = (object) $data; $oldid = $data->id; $data->courseid = $this->get_courseid(); $owneremail = empty($data->owneremail) ? join(array_splice(explode(".", $data->ownerun), 0, -1)) : $data->owneremail; $owner = $DB->get_record('user', array('email' => $owneremail)); if ($owner) { $data->ownerid = $owner->id; } else { // Turnitin class owner not found from email address etc create user account $i = 0; $newuser = false; while (!is_object($newuser)) { // Keep trying to create a new username $username = $i == 0 ? $data->ownerun : $data->ownerun . '_' . $i; // Append number if username exists $i++; $newuser = create_user_record($username, substr($i . "-" . md5($username), 0, 8)); if (is_object($newuser)) { $newuser->email = $owneremail; $newuser->firstname = $data->ownerfn; $newuser->lastname = $data->ownerln; if (!$DB->update_record("user", $newuser)) { turnitintool_print_error('userupdateerror', 'turnitintool'); } } } $data->ownerid = $newuser->id; } $tiiowner = new object(); $tiiowner->userid = $data->ownerid; $tiiowner->turnitin_uid = $data->ownertiiuid; if (!($tiiuser = $DB->get_record('turnitintool_users', array('userid' => $data->ownerid)))) { $DB->insert_record('turnitintool_users', $tiiowner); } if (!$DB->get_records_select('turnitintool_courses', 'courseid=' . $data->courseid)) { $newitemid = $DB->insert_record('turnitintool_courses', $data); $this->set_mapping('turnitintool_courses', $oldid, $newitemid); } }
/** * Copied from moodlelib:authenticate_user_login() * * WHY? because I need to hard code the plugins to auth_saml, and this user * may be set to any number of other types of login method * * First of all - make sure that they aren't nologin - we don't mess with that! * * * Given a username and password, this function looks them * up using the currently selected authentication mechanism, * and if the authentication is successful, it returns a * valid $user object from the 'user' table. * * Uses auth_ functions from the currently active auth module * * After authenticate_user_login() returns success, you will need to * log that the user has logged in, and call complete_user_login() to set * the session up. * * @uses $CFG * @param string $saml_account_matcher Field will be used in order to find the user account. * @param array $user_saml User's info (with system magic quotes) * @param boolean $saml_create Auto-provision user * @param boolean $saml_update Auto-update user * @return user|flase A {@link $USER} object or false if error */ function auth_onelogin_saml_authenticate_user_login($saml_account_matcher, $user_saml, $saml_create = false, $saml_update = false) { global $CFG, $DB; // ensure that only saml auth module is chosen $authsenabled = get_enabled_auth_plugins(); $password = time(); $created = false; if ($user = get_complete_user_data($saml_account_matcher, $user_saml[$saml_account_matcher])) { $auth = empty($user->auth) ? 'manual' : $user->auth; // use manual if auth not set if ($auth == 'nologin' or !is_enabled_auth($auth)) { add_to_log(0, 'login', 'error', 'index.php', $user_saml[$saml_account_matcher]); print_error('[client ' . getremoteaddr() . '] ' . $CFG->wwwroot . ' ---> DISABLED LOGIN: '******' ' . $_SERVER['HTTP_USER_AGENT']); return false; } } else { // check if there's a deleted record (cheaply) $query_conditions[$saml_account_matcher] = $user_saml[$saml_account_matcher]; $query_conditions['deleted'] = 1; if ($DB->get_field('user', 'id', $query_conditions)) { print_error('[client ' . $_SERVER['REMOTE_ADDR'] . '] ' . $CFG->wwwroot . ' ---> DELETED LOGIN: '******' ' . $_SERVER['HTTP_USER_AGENT']); return false; } $auths = $authsenabled; $user = new object(); $user->id = 0; // User does not exist } // hard code SAML $auths = array('onelogin_saml'); foreach ($auths as $auth) { $authplugin = get_auth_plugin($auth); // on auth fail fall through to the next plugin if (!$authplugin->user_login($user_saml[$saml_account_matcher], $password)) { continue; } if (!$user->id) { // if user not found, // create him if ($saml_create) { $user = create_user_record($user_saml[$saml_account_matcher], $password, $auth); $authplugin->sync_roles($user); $created = true; } } if ($user->id && !$created) { if (empty($user->auth)) { // For some reason auth isn't set yet $query_conditions['id'] = $user->id; $DB->set_field('user', 'auth', $auth, $query_conditions); $user->auth = $auth; } // User already exists in database if ($saml_update) { if (empty($user->firstaccess)) { //prevent firstaccess from remaining 0 for manual account that never required confirmation $query_conditions['id'] = $user->id; $DB->set_field('user', 'firstaccess', $user->timemodified, $query_conditions); $user->firstaccess = $user->timemodified; } if (!empty($user_saml['username']) && $user->username != $user_saml['username']) { $query_conditions['id'] = $user->id; $DB->set_field('user', 'username', $user_saml['username'], $query_conditions); $user->email = $user_saml['username']; } if (!empty($user_saml['email']) && $user->email != $user_saml['email']) { $query_conditions['id'] = $user->id; $DB->set_field('user', 'email', $user_saml['email'], $query_conditions); $user->email = $user_saml['email']; } if (!empty($user_saml['firstname']) && $user->firstname != $user_saml['firstname']) { $query_conditions['id'] = $user->id; $DB->set_field('user', 'firstname', $user_saml['firstname'], $query_conditions); $user->firstname = $user_saml['firstname']; } if (!empty($user_saml['lastname']) && $user->lastname != $user_saml['lastname']) { $query_conditions['id'] = $user->id; $DB->set_field('user', 'lastname', $user_saml['lastname'], $query_conditions); $user->lastname = $user_saml['lastname']; } $authplugin->sync_roles($user); } // we don't want to upset the existing authentication schema for the user // update_internal_user_password($user, $password); // just in case salt or encoding were changed (magic quotes too one day) // update user record from external DB /* if (!$authplugin->is_internal()) { $user = update_user_record($user->username, get_auth_plugin($user->auth)); } */ } foreach ($authsenabled as $hau) { $hauth = get_auth_plugin($hau); $hauth->user_authenticated_hook($user, $user_saml[$saml_account_matcher], $password); } if (!$user->id && !$saml_create) { print_error("User provided by the IdP" . ' "' . $user_saml[$saml_account_matcher] . '" ' . "not exists in moodle and auto-provisioning is disabled"); return false; } return $user; } // failed if all the plugins have failed add_to_log(0, 'login', 'error', 'index.php', $username); print_error('[client ' . getremoteaddr() . "] {$CFG->wwwroot} ---> FAILED LOGIN: {$username} " . $_SERVER['HTTP_USER_AGENT']); return false; }
/** * Authenticates a user against the chosen authentication mechanism * * Given a username and password, this function looks them * up using the currently selected authentication mechanism, * and if the authentication is successful, it returns a * valid $user object from the 'user' table. * * Uses auth_ functions from the currently active auth module * * After authenticate_user_login() returns success, you will need to * log that the user has logged in, and call complete_user_login() to set * the session up. * * Note: this function works only with non-mnet accounts! * * @param string $username User's username (or also email if $CFG->authloginviaemail enabled) * @param string $password User's password * @param bool $ignorelockout useful when guessing is prevented by other mechanism such as captcha or SSO * @param int $failurereason login failure reason, can be used in renderers (it may disclose if account exists) * @return stdClass|false A {@link $USER} object or false if error */ function authenticate_user_login($username, $password, $ignorelockout = false, &$failurereason = null) { global $CFG, $DB; require_once "{$CFG->libdir}/authlib.php"; if ($user = get_complete_user_data('username', $username, $CFG->mnet_localhost_id)) { // we have found the user } else { if (!empty($CFG->authloginviaemail)) { if ($email = clean_param($username, PARAM_EMAIL)) { $select = "mnethostid = :mnethostid AND LOWER(email) = LOWER(:email) AND deleted = 0"; $params = array('mnethostid' => $CFG->mnet_localhost_id, 'email' => $email); $users = $DB->get_records_select('user', $select, $params, 'id', 'id', 0, 2); if (count($users) === 1) { // Use email for login only if unique. $user = reset($users); $user = get_complete_user_data('id', $user->id); $username = $user->username; } unset($users); } } } $authsenabled = get_enabled_auth_plugins(); if ($user) { // Use manual if auth not set. $auth = empty($user->auth) ? 'manual' : $user->auth; if (in_array($user->auth, $authsenabled)) { $authplugin = get_auth_plugin($user->auth); $authplugin->pre_user_login_hook($user); } if (!empty($user->suspended)) { $failurereason = AUTH_LOGIN_SUSPENDED; // Trigger login failed event. $event = \core\event\user_login_failed::create(array('userid' => $user->id, 'other' => array('username' => $username, 'reason' => $failurereason))); $event->trigger(); error_log('[client ' . getremoteaddr() . "] {$CFG->wwwroot} Suspended Login: {$username} " . $_SERVER['HTTP_USER_AGENT']); return false; } if ($auth == 'nologin' or !is_enabled_auth($auth)) { // Legacy way to suspend user. $failurereason = AUTH_LOGIN_SUSPENDED; // Trigger login failed event. $event = \core\event\user_login_failed::create(array('userid' => $user->id, 'other' => array('username' => $username, 'reason' => $failurereason))); $event->trigger(); error_log('[client ' . getremoteaddr() . "] {$CFG->wwwroot} Disabled Login: {$username} " . $_SERVER['HTTP_USER_AGENT']); return false; } $auths = array($auth); } else { // Check if there's a deleted record (cheaply), this should not happen because we mangle usernames in delete_user(). if ($DB->get_field('user', 'id', array('username' => $username, 'mnethostid' => $CFG->mnet_localhost_id, 'deleted' => 1))) { $failurereason = AUTH_LOGIN_NOUSER; // Trigger login failed event. $event = \core\event\user_login_failed::create(array('other' => array('username' => $username, 'reason' => $failurereason))); $event->trigger(); error_log('[client ' . getremoteaddr() . "] {$CFG->wwwroot} Deleted Login: {$username} " . $_SERVER['HTTP_USER_AGENT']); return false; } // User does not exist. $auths = $authsenabled; $user = new stdClass(); $user->id = 0; } if ($ignorelockout) { // Some other mechanism protects against brute force password guessing, for example login form might include reCAPTCHA // or this function is called from a SSO script. } else { if ($user->id) { // Verify login lockout after other ways that may prevent user login. if (login_is_lockedout($user)) { $failurereason = AUTH_LOGIN_LOCKOUT; // Trigger login failed event. $event = \core\event\user_login_failed::create(array('userid' => $user->id, 'other' => array('username' => $username, 'reason' => $failurereason))); $event->trigger(); error_log('[client ' . getremoteaddr() . "] {$CFG->wwwroot} Login lockout: {$username} " . $_SERVER['HTTP_USER_AGENT']); return false; } } else { // We can not lockout non-existing accounts. } } foreach ($auths as $auth) { $authplugin = get_auth_plugin($auth); // On auth fail fall through to the next plugin. if (!$authplugin->user_login($username, $password)) { continue; } // Successful authentication. if ($user->id) { // User already exists in database. if (empty($user->auth)) { // For some reason auth isn't set yet. $DB->set_field('user', 'auth', $auth, array('id' => $user->id)); $user->auth = $auth; } // If the existing hash is using an out-of-date algorithm (or the legacy md5 algorithm), then we should update to // the current hash algorithm while we have access to the user's password. update_internal_user_password($user, $password); if ($authplugin->is_synchronised_with_external()) { // Update user record from external DB. $user = update_user_record_by_id($user->id); } } else { // The user is authenticated but user creation may be disabled. if (!empty($CFG->authpreventaccountcreation)) { $failurereason = AUTH_LOGIN_UNAUTHORISED; // Trigger login failed event. $event = \core\event\user_login_failed::create(array('other' => array('username' => $username, 'reason' => $failurereason))); $event->trigger(); error_log('[client ' . getremoteaddr() . "] {$CFG->wwwroot} Unknown user, can not create new accounts: {$username} " . $_SERVER['HTTP_USER_AGENT']); return false; } else { $user = create_user_record($username, $password, $auth); } } $authplugin->sync_roles($user); foreach ($authsenabled as $hau) { $hauth = get_auth_plugin($hau); $hauth->user_authenticated_hook($user, $username, $password); } if (empty($user->id)) { $failurereason = AUTH_LOGIN_NOUSER; // Trigger login failed event. $event = \core\event\user_login_failed::create(array('other' => array('username' => $username, 'reason' => $failurereason))); $event->trigger(); return false; } if (!empty($user->suspended)) { // Just in case some auth plugin suspended account. $failurereason = AUTH_LOGIN_SUSPENDED; // Trigger login failed event. $event = \core\event\user_login_failed::create(array('userid' => $user->id, 'other' => array('username' => $username, 'reason' => $failurereason))); $event->trigger(); error_log('[client ' . getremoteaddr() . "] {$CFG->wwwroot} Suspended Login: {$username} " . $_SERVER['HTTP_USER_AGENT']); return false; } login_attempt_valid($user); $failurereason = AUTH_LOGIN_OK; return $user; } // Failed if all the plugins have failed. if (debugging('', DEBUG_ALL)) { error_log('[client ' . getremoteaddr() . "] {$CFG->wwwroot} Failed Login: {$username} " . $_SERVER['HTTP_USER_AGENT']); } if ($user->id) { login_attempt_failed($user); $failurereason = AUTH_LOGIN_FAILED; // Trigger login failed event. $event = \core\event\user_login_failed::create(array('userid' => $user->id, 'other' => array('username' => $username, 'reason' => $failurereason))); $event->trigger(); } else { $failurereason = AUTH_LOGIN_NOUSER; // Trigger login failed event. $event = \core\event\user_login_failed::create(array('other' => array('username' => $username, 'reason' => $failurereason))); $event->trigger(); } return false; }
require_once $CFG->libdir . '/gdlib.php'; // True to download a gravatar. define('MDK_AVATAR', true); $data = "s1,test,Eric,Cartman,s1@example.com\ns2,test,Stan,Marsh,s2@example.com\ns3,test,Kyle,Broflovski,s3@example.com\ns4,test,Kenny,McCormick,s4@example.com\ns5,test,Butters,Stotch,s5@example.com\ns6,test,Clyde,Donovan,s6@example.com\ns7,test,Jimmy,Valmer,s7@example.com\ns8,test,Timmy,Burch,s8@example.com\ns9,test,Wendy,Testaburger,s9@example.com\ns10,test,Bebe,Stevens,s10@example.com\nt1,test,Herbert,Garrison,t1@example.com\nt2,test,Sheila,Brovslovski,t2@example.com\nt3,test,Liane,Cartman,t3@example.com\nm1,test,Officer,Barbady,m1@example.com\nm2,test,Principal,Victoria,m2@example.com\nm3,test,Randy,Marsh,m3@example.com"; $users = explode("\n", $data); // Create all the users. foreach ($users as $user) { if (empty($user)) { continue; } $user = explode(',', $user); if ($DB->record_exists('user', array('username' => $user[0], 'deleted' => 0))) { continue; } mtrace('Creating user ' . $user[0]); $u = create_user_record($user[0], $user[1]); $u->firstname = $user[2]; $u->lastname = $user[3]; $u->email = $user[4]; $u->city = 'Perth'; $u->country = 'AU'; $u->lang = 'en'; $u->description = 'Who\'s your daddy?'; $u->url = 'http://moodle.org'; $u->idnumber = ''; $u->institution = 'Moodle HQ'; $u->department = 'Rock on!'; $u->phone1 = ''; $u->phone2 = ''; $u->address = ''; // Adds an avatar to the user. Will slow down the process.
/** * Authenticates a user against the chosen authentication mechanism * * Given a username and password, this function looks them * up using the currently selected authentication mechanism, * and if the authentication is successful, it returns a * valid $user object from the 'user' table. * * Uses auth_ functions from the currently active auth module * * After authenticate_user_login() returns success, you will need to * log that the user has logged in, and call complete_user_login() to set * the session up. * * Note: this function works only with non-mnet accounts! * * @param string $username User's username * @param string $password User's password * @return user|flase A {@link $USER} object or false if error */ function authenticate_user_login($username, $password) { global $CFG, $DB; $authsenabled = get_enabled_auth_plugins(); if ($user = get_complete_user_data('username', $username, $CFG->mnet_localhost_id)) { $auth = empty($user->auth) ? 'manual' : $user->auth; // use manual if auth not set if (!empty($user->suspended)) { add_to_log(SITEID, 'login', 'error', 'index.php', $username); error_log('[client ' . getremoteaddr() . "] {$CFG->wwwroot} Suspended Login: {$username} " . $_SERVER['HTTP_USER_AGENT']); return false; } if ($auth == 'nologin' or !is_enabled_auth($auth)) { add_to_log(SITEID, 'login', 'error', 'index.php', $username); error_log('[client ' . getremoteaddr() . "] {$CFG->wwwroot} Disabled Login: {$username} " . $_SERVER['HTTP_USER_AGENT']); return false; } $auths = array($auth); } else { // check if there's a deleted record (cheaply) if ($DB->get_field('user', 'id', array('username' => $username, 'deleted' => 1))) { error_log('[client ' . getremoteaddr() . "] {$CFG->wwwroot} Deleted Login: {$username} " . $_SERVER['HTTP_USER_AGENT']); return false; } // User does not exist $auths = $authsenabled; $user = new stdClass(); $user->id = 0; } foreach ($auths as $auth) { $authplugin = get_auth_plugin($auth); // on auth fail fall through to the next plugin if (!$authplugin->user_login($username, $password)) { continue; } // successful authentication if ($user->id) { // User already exists in database if (empty($user->auth)) { // For some reason auth isn't set yet $DB->set_field('user', 'auth', $auth, array('username' => $username)); $user->auth = $auth; } if (empty($user->firstaccess)) { //prevent firstaccess from remaining 0 for manual account that never required confirmation $DB->set_field('user', 'firstaccess', $user->timemodified, array('id' => $user->id)); $user->firstaccess = $user->timemodified; } update_internal_user_password($user, $password); // just in case salt or encoding were changed (magic quotes too one day) if ($authplugin->is_synchronised_with_external()) { // update user record from external DB $user = update_user_record($username); } } else { // if user not found, create him $user = create_user_record($username, $password, $auth); } $authplugin->sync_roles($user); foreach ($authsenabled as $hau) { $hauth = get_auth_plugin($hau); $hauth->user_authenticated_hook($user, $username, $password); } if (empty($user->id)) { return false; } if (!empty($user->suspended)) { // just in case some auth plugin suspended account add_to_log(SITEID, 'login', 'error', 'index.php', $username); error_log('[client ' . getremoteaddr() . "] {$CFG->wwwroot} Suspended Login: {$username} " . $_SERVER['HTTP_USER_AGENT']); return false; } return $user; } // failed if all the plugins have failed add_to_log(SITEID, 'login', 'error', 'index.php', $username); if (debugging('', DEBUG_ALL)) { error_log('[client ' . getremoteaddr() . "] {$CFG->wwwroot} Failed Login: {$username} " . $_SERVER['HTTP_USER_AGENT']); } return false; }
/** * Creates an User with given information. Required fields are: * -username * -idnumber * -firstname * -lastname * -email * * And there's some interesting fields: * -password * -auth * -confirmed * -timezone * -country * -emailstop * -theme * -lang * -mailformat * * @param assoc array or object $user * * @return string or thrown exceptions */ function create_user($user) { global $CFG, $DB; /// WS: convert user array into an user object if (is_array($user)) { $user = (object) $user; } /// check auth fields if (!isset($user->auth)) { $user->auth = 'manual'; } else { /// check that the auth value exists $authplugin = get_directory_list($CFG->dirroot . "/auth", '', false, true, false); if (array_search($user->auth, $authplugin) === false) { throw new moodle_exception('authnotexisting'); } } $required = array('username', 'firstname', 'lastname', 'email', 'password'); foreach ($required as $req) { if (!isset($user->{$req})) { throw new moodle_exception('missingrequiredfield'); } } $password = hash_internal_user_password($user->password); $record = create_user_record($user->username, $password, $user->auth); if ($record) { $user->id = $record->id; if ($DB->update_record('user', $user)) { return $record->id; } else { //we could not update properly the newly created user, we need to delete it $DB->delete_record('user', array('id' => $record->id)); throw new moodle_exception('usernotcreated'); } } throw new moodle_exception('usernotcreated'); }
function create_moodle_only_user($user_data) { global $CFG, $DB; $username = $user_data['username']; $username = utf8_decode($username); $username = strtolower($username); /* Creamos el nuevo usuario de Moodle si no está creado */ $conditions = array('username' => $username); $user = $DB->get_record('user', $conditions); if (!$user) { $user = create_user_record($username, "", "manual"); } if (array_key_exists('password', $user_data)) { $password = utf8_decode($user_data['password']); } else { $password = ''; } if (array_key_exists('email', $user_data)) { $email = utf8_decode($user_data['email']); } else { $email = ''; } if (array_key_exists('firstname', $user_data)) { $firstname = utf8_decode($user_data['firstname']); } else { $firstname = ''; } if (array_key_exists('lastname', $user_data)) { $lastname = utf8_decode($user_data['lastname']); } else { $lastname = ''; } if (array_key_exists('city', $user_data)) { $city = utf8_decode($user_data['city']); } else { $city = ''; } if (array_key_exists('country', $user_data)) { $country = utf8_decode($user_data['country']); } else { $country = ''; } $conditions = array('id' => $user->id); if ($firstname) { $DB->set_field('user', 'firstname', $firstname, $conditions); } if ($lastname) { $DB->set_field('user', 'lastname', $lastname, $conditions); } if ($email) { $DB->set_field('user', 'email', $email, $conditions); } if ($city) { $DB->set_field('user', 'city', $city, $conditions); } if ($country) { $DB->set_field('user', 'country', $country, $conditions); } update_internal_user_password($user, $password); }
function loginpage_hook() { global $CFG, $SESSION, $DB, $USER; require_once $CFG->dirroot . '/auth/vatsim/config.php'; // initiate the SSO class with consumer details and encryption details $SSO = new SSO($sso['base'], $sso['key'], $sso['secret'], $sso['method'], $sso['cert']); // return variable is needed later in this script $sso_return = $sso['return']; // remove other config variables unset($sso); // if VATSIM has redirected the member back if (isset($_GET['oauth_verifier']) && !isset($_GET['oauth_cancel'])) { // check to make sure there is a saved token for this user if (isset($_SESSION[SSO_SESSION]) && isset($_SESSION[SSO_SESSION]['key']) && isset($_SESSION[SSO_SESSION]['secret'])) { if (@$_GET['oauth_token'] != $_SESSION[SSO_SESSION]['key']) { throw new moodle_exception("An error occurred with the login process - please try again", 'auth_vatsim'); } if (@(!isset($_GET['oauth_verifier']))) { throw new moodle_exception("An error occurred with the login process", 'auth_vatsim'); } // obtain the details of this user from VATSIM $vatsimUser = $SSO->checkLogin($_SESSION[SSO_SESSION]['key'], $_SESSION[SSO_SESSION]['secret'], @$_GET['oauth_verifier']); if ($vatsimUser) { // One-time use of tokens, token no longer valid unset($_SESSION[SSO_SESSION]); $vatsim = $vatsimUser->user; //print_r($user->user); $username = $vatsim->id; // plugin only designed where email address is returned, if no email specified, if (@empty($vatsim->email)) { throw new moodle_exception('noemail', "auth_vatsim"); } $useremail = $vatsim->email; // find the user in the current database, by CID, not email $user = $DB->get_record('user', array('username' => $username, 'deleted' => 0, 'mnethostid' => $CFG->mnet_localhost_id)); // create the user if it doesn't exist if (empty($user)) { // deny login if setting "Prevent account creation when authenticating" is on if ($CFG->authpreventaccountcreation) { throw new moodle_exception("noaccountyet", "auth_vatsim"); } //retrieve more information from the provider $newuser = new stdClass(); $newuser->email = $useremail; $newuser->firstname = $vatsim->name_first; $newuser->lastname = $vatsim->name_last; $newuser->country = $vatsim->country->code; create_user_record($username, '', 'vatsim'); } else { $username = $user->username; } add_to_log(SITEID, 'auth_vatsim', '', '', $username . '/' . $useremail); $user = authenticate_user_login($username, null); if ($user) { //prefill more user information if new user if (!empty($newuser)) { $newuser->id = $user->id; $DB->update_record('user', $newuser); $user = (object) array_merge((array) $user, (array) $newuser); } complete_user_login($user); // Redirection if (user_not_fully_set_up($USER)) { $urltogo = $CFG->wwwroot . '/user/edit.php'; // We don't delete $SESSION->wantsurl yet, so we get there later } else { if (isset($SESSION->wantsurl) and strpos($SESSION->wantsurl, $CFG->wwwroot) === 0) { $urltogo = $SESSION->wantsurl; // Because it's an address in this site unset($SESSION->wantsurl); } else { // No wantsurl stored or external - go to homepage $urltogo = $CFG->wwwroot . '/'; unset($SESSION->wantsurl); } } redirect($urltogo); } } else { // OAuth or cURL errors have occurred //$error = $SSO->error(); throw new moodle_exception("An error occurred with the login process", 'auth_vatsim'); } } // the user cancelled their login and were sent back } else { if (isset($_GET['oauth_cancel'])) { throw new moodle_exception("You cancelled your login", 'auth_vatsim'); } } // create a request token for this login. Provides return URL and suspended/inactive settings $token = $SSO->requestToken($sso_return, false, false); if ($token) { // store the token information in the session so that we can retrieve it when the user returns $_SESSION[SSO_SESSION] = array('key' => (string) $token->token->oauth_token, 'secret' => (string) $token->token->oauth_token_secret); // redirect the member to VATSIM $SSO->sendToVatsim(); } else { throw new moodle_exception("An error occurred with the login process", 'auth_vatsim'); } }
/** * Authentication hook - is called every time user hit the login page * The code is run only if the param code is mentionned. */ function loginpage_hook() { global $USER, $SESSION, $CFG, $DB; //check the Google authorization code $authorizationcode = optional_param('code', '', PARAM_TEXT); if (!empty($authorizationcode)) { $authprovider = required_param('authprovider', PARAM_ALPHANUMEXT); //set the params specific to the authentication provider $params = array(); switch ($authprovider) { case 'google': $params['client_id'] = get_config('auth/googleoauth2', 'googleclientid'); $params['client_secret'] = get_config('auth/googleoauth2', 'googleclientsecret'); $requestaccesstokenurl = 'https://accounts.google.com/o/oauth2/token'; $params['grant_type'] = 'authorization_code'; $params['redirect_uri'] = $CFG->wwwroot . '/auth/googleoauth2/google_redirect.php'; $params['code'] = $authorizationcode; break; case 'facebook': $params['client_id'] = get_config('auth/googleoauth2', 'facebookclientid'); $params['client_secret'] = get_config('auth/googleoauth2', 'facebookclientsecret'); $requestaccesstokenurl = 'https://graph.facebook.com/oauth/access_token'; $params['redirect_uri'] = $CFG->wwwroot . '/auth/googleoauth2/facebook_redirect.php'; $params['code'] = $authorizationcode; break; case 'messenger': $params['client_id'] = get_config('auth/googleoauth2', 'messengerclientid'); $params['client_secret'] = get_config('auth/googleoauth2', 'messengerclientsecret'); $requestaccesstokenurl = 'https://oauth.live.com/token'; $params['redirect_uri'] = $CFG->wwwroot . '/auth/googleoauth2/messenger_redirect.php'; $params['code'] = $authorizationcode; $params['grant_type'] = 'authorization_code'; break; case 'github': $params['client_id'] = get_config('auth/googleoauth2', 'githubclientid'); $params['client_secret'] = get_config('auth/googleoauth2', 'githubclientsecret'); $requestaccesstokenurl = 'https://github.com/login/oauth/access_token'; $params['redirect_uri'] = $CFG->wwwroot . '/auth/googleoauth2/github_redirect.php'; $params['code'] = $authorizationcode; break; case 'linkedin': $params['grant_type'] = 'authorization_code'; $params['code'] = $authorizationcode; $params['redirect_uri'] = $CFG->wwwroot . '/auth/googleoauth2/linkedin_redirect.php'; $params['client_id'] = get_config('auth/googleoauth2', 'linkedinclientid'); $params['client_secret'] = get_config('auth/googleoauth2', 'linkedinclientsecret'); $requestaccesstokenurl = 'https://www.linkedin.com/uas/oauth2/accessToken'; break; default: throw new moodle_exception('unknown_oauth2_provider'); break; } //request by curl an access token and refresh token require_once $CFG->libdir . '/filelib.php'; if ($authprovider == 'messenger') { //Windows Live returns an "Object moved" error with curl->post() encoding $curl = new curl(); $postreturnvalues = $curl->get('https://oauth.live.com/token?client_id=' . urlencode($params['client_id']) . '&redirect_uri=' . urlencode($params['redirect_uri']) . '&client_secret=' . urlencode($params['client_secret']) . '&code=' . urlencode($params['code']) . '&grant_type=authorization_code'); } else { if ($authprovider == 'linkedin') { $curl = new curl(); $postreturnvalues = $curl->get($requestaccesstokenurl . '?client_id=' . urlencode($params['client_id']) . '&redirect_uri=' . urlencode($params['redirect_uri']) . '&client_secret=' . urlencode($params['client_secret']) . '&code=' . urlencode($params['code']) . '&grant_type=authorization_code'); } else { $curl = new curl(); $postreturnvalues = $curl->post($requestaccesstokenurl, $params); } } switch ($authprovider) { case 'google': case 'linkedin': $postreturnvalues = json_decode($postreturnvalues); $accesstoken = $postreturnvalues->access_token; //$refreshtoken = $postreturnvalues->refresh_token; //$expiresin = $postreturnvalues->expires_in; //$tokentype = $postreturnvalues->token_type; break; case 'facebook': case 'github': parse_str($postreturnvalues, $returnvalues); $accesstoken = $returnvalues['access_token']; break; case 'messenger': $accesstoken = json_decode($postreturnvalues)->access_token; break; default: break; } //with access token request by curl the email address if (!empty($accesstoken)) { //get the username matching the email switch ($authprovider) { case 'google': $params = array(); $params['access_token'] = $accesstoken; $params['alt'] = 'json'; $postreturnvalues = $curl->get('https://www.googleapis.com/userinfo/email', $params); $postreturnvalues = json_decode($postreturnvalues); $useremail = $postreturnvalues->data->email; $verified = $postreturnvalues->data->isVerified; break; case 'facebook': $params = array(); $params['access_token'] = $accesstoken; $postreturnvalues = $curl->get('https://graph.facebook.com/me', $params); $facebookuser = json_decode($postreturnvalues); $useremail = $facebookuser->email; $verified = $facebookuser->verified; break; case 'messenger': $params = array(); $params['access_token'] = $accesstoken; $postreturnvalues = $curl->get('https://apis.live.net/v5.0/me', $params); $messengeruser = json_decode($postreturnvalues); $useremail = $messengeruser->emails->preferred; $verified = 1; //not super good but there are no way to check it yet: //http://social.msdn.microsoft.com/Forums/en-US/messengerconnect/thread/515d546d-1155-4775-95d8-89dadc5ee929 break; case 'github': $params = array(); $params['access_token'] = $accesstoken; $postreturnvalues = $curl->get('https://api.github.com/user', $params); $githubuser = json_decode($postreturnvalues); $useremails = json_decode($curl->get('https://api.github.com/user/emails', $params)); $useremail = $useremails[0]; $verified = 1; // The field will be available in the final version of the API v3. break; case 'linkedin': $params = array(); $params['format'] = 'json'; $params['oauth2_access_token'] = $accesstoken; $postreturnvalues = $curl->get('https://api.linkedin.com/v1/people/~:(first-name,last-name,email-address,location:(name,country:(code)))', $params); $linkedinuser = json_decode($postreturnvalues); $useremail = $linkedinuser->emailAddress; $verified = 1; break; default: break; } //throw an error if the email address is not verified if (!$verified) { throw new moodle_exception('emailaddressmustbeverified', 'auth_googleoauth2'); } // Prohibit login if email belongs to the prohibited domain if ($err = email_is_not_allowed($useremail)) { throw new moodle_exception($err, 'auth_googleoauth2'); } //if email not existing in user database then create a new username (userX). if (empty($useremail) or $useremail != clean_param($useremail, PARAM_EMAIL)) { throw new moodle_exception('couldnotgetuseremail'); //TODO: display a link for people to retry } //get the user - don't bother with auth = googleoauth2 because //authenticate_user_login() will fail it if it's not 'googleoauth2' $user = $DB->get_record('user', array('email' => $useremail, 'deleted' => 0, 'mnethostid' => $CFG->mnet_localhost_id)); //create the user if it doesn't exist if (empty($user)) { // deny login if setting "Prevent account creation when authenticating" is on if ($CFG->authpreventaccountcreation) { throw new moodle_exception("noaccountyet", "auth_googleoauth2"); } //get following incremented username $lastusernumber = get_config('auth/googleoauth2', 'lastusernumber'); $lastusernumber = empty($lastusernumber) ? 1 : $lastusernumber++; //check the user doesn't exist $nextuser = $DB->get_record('user', array('username' => get_config('auth/googleoauth2', 'googleuserprefix') . $lastusernumber)); while (!empty($nextuser)) { $lastusernumber = $lastusernumber + 1; $nextuser = $DB->get_record('user', array('username' => get_config('auth/googleoauth2', 'googleuserprefix') . $lastusernumber)); } set_config('lastusernumber', $lastusernumber, 'auth/googleoauth2'); $username = get_config('auth/googleoauth2', 'googleuserprefix') . $lastusernumber; //retrieve more information from the provider $newuser = new stdClass(); $newuser->email = $useremail; switch ($authprovider) { case 'google': $params = array(); $params['access_token'] = $accesstoken; $params['alt'] = 'json'; $userinfo = $curl->get('https://www.googleapis.com/oauth2/v1/userinfo', $params); $userinfo = json_decode($userinfo); //email, id, name, verified_email, given_name, family_name, link, gender, locale $newuser->auth = 'googleoauth2'; if (!empty($userinfo->given_name)) { $newuser->firstname = $userinfo->given_name; } if (!empty($userinfo->family_name)) { $newuser->lastname = $userinfo->family_name; } if (!empty($userinfo->locale)) { //$newuser->lang = $userinfo->locale; //TODO: convert the locale into correct Moodle language code } break; case 'facebook': $newuser->firstname = $facebookuser->first_name; $newuser->lastname = $facebookuser->last_name; break; case 'messenger': $newuser->firstname = $messengeruser->first_name; $newuser->lastname = $messengeruser->last_name; break; case 'github': //As Github doesn't provide firstname/lastname, we'll split the name at the first whitespace. $githubusername = explode(' ', $githubuser->name, 2); $newuser->firstname = $githubusername[0]; $newuser->lastname = $githubusername[1]; break; case 'linkedin': $newuser->firstname = $linkedinuser->firstName; $newuser->lastname = $linkedinuser->lastName; $newuser->country = $linkedinuser->country->code; $newuser->city = $linkedinuser->name; break; default: break; } //retrieve country and city if the provider failed to give it if (!isset($newuser->country) or !isset($newuser->city)) { $googleipinfodbkey = get_config('auth/googleoauth2', 'googleipinfodbkey'); if (!empty($googleipinfodbkey)) { $locationdata = $curl->get('http://api.ipinfodb.com/v3/ip-city/?key=' . $googleipinfodbkey . '&ip=' . getremoteaddr() . '&format=json'); $locationdata = json_decode($locationdata); } if (!empty($locationdata)) { //TODO: check that countryCode does match the Moodle country code $newuser->country = isset($newuser->country) ? isset($newuser->country) : $locationdata->countryCode; $newuser->city = isset($newuser->city) ? isset($newuser->city) : $locationdata->cityName; } } create_user_record($username, '', 'googleoauth2'); } else { $username = $user->username; } //authenticate the user //TODO: delete this log later $userid = empty($user) ? 'new user' : $user->id; add_to_log(SITEID, 'auth_googleoauth2', '', '', $username . '/' . $useremail . '/' . $userid); $user = authenticate_user_login($username, null); if ($user) { //set a cookie to remember what auth provider was selected setcookie('MOODLEGOOGLEOAUTH2_' . $CFG->sessioncookie, $authprovider, time() + DAYSECS * 60, $CFG->sessioncookiepath, $CFG->sessioncookiedomain, $CFG->cookiesecure, $CFG->cookiehttponly); //prefill more user information if new user if (!empty($newuser)) { $newuser->id = $user->id; $DB->update_record('user', $newuser); $user = (object) array_merge((array) $user, (array) $newuser); } complete_user_login($user); // Redirection if (user_not_fully_set_up($USER)) { $urltogo = $CFG->wwwroot . '/user/edit.php'; // We don't delete $SESSION->wantsurl yet, so we get there later } else { if (isset($SESSION->wantsurl) and strpos($SESSION->wantsurl, $CFG->wwwroot) === 0) { $urltogo = $SESSION->wantsurl; // Because it's an address in this site unset($SESSION->wantsurl); } else { // No wantsurl stored or external - go to homepage $urltogo = $CFG->wwwroot . '/'; unset($SESSION->wantsurl); } } redirect($urltogo); } } else { throw new moodle_exception('couldnotgetgoogleaccesstoken', 'auth_googleoauth2'); } } }
/** * Authenticates a user against the chosen authentication mechanism * * Given a username and password, this function looks them * up using the currently selected authentication mechanism, * and if the authentication is successful, it returns a * valid $user object from the 'user' table. * * Uses auth_ functions from the currently active auth module * * After authenticate_user_login() returns success, you will need to * log that the user has logged in, and call complete_user_login() to set * the session up. * * Note: this function works only with non-mnet accounts! * * @param string $username User's username * @param string $password User's password * @return user|flase A {@link $USER} object or false if error */ function authenticate_user_login($username, $password) { global $CFG, $DB; $authsenabled = get_enabled_auth_plugins(); if ($user = get_complete_user_data('username', $username, $CFG->mnet_localhost_id)) { $auth = empty($user->auth) ? 'manual' : $user->auth; // use manual if auth not set if (!empty($user->suspended)) { add_to_log(SITEID, 'login', 'error', 'index.php', $username); error_log('[client '.getremoteaddr()."] $CFG->wwwroot Suspended Login: $username ".$_SERVER['HTTP_USER_AGENT']); return false; } if ($auth=='nologin' or !is_enabled_auth($auth)) { add_to_log(SITEID, 'login', 'error', 'index.php', $username); error_log('[client '.getremoteaddr()."] $CFG->wwwroot Disabled Login: $username ".$_SERVER['HTTP_USER_AGENT']); return false; } $auths = array($auth); } else { // Check if there's a deleted record (cheaply), this should not happen because we mangle usernames in delete_user(). if ($DB->get_field('user', 'id', array('username'=>$username, 'mnethostid'=>$CFG->mnet_localhost_id, 'deleted'=>1))) { error_log('[client '.getremoteaddr()."] $CFG->wwwroot Deleted Login: $username ".$_SERVER['HTTP_USER_AGENT']); return false; } // Do not try to authenticate non-existent accounts when user creation is not disabled. if (!empty($CFG->authpreventaccountcreation)) { add_to_log(SITEID, 'login', 'error', 'index.php', $username); error_log('[client '.getremoteaddr()."] $CFG->wwwroot Unknown user, can not create new accounts: $username ".$_SERVER['HTTP_USER_AGENT']); return false; } // User does not exist $auths = $authsenabled; $user = new stdClass(); $user->id = 0; } foreach ($auths as $auth) { $authplugin = get_auth_plugin($auth); // on auth fail fall through to the next plugin if (!$authplugin->user_login($username, $password)) { continue; } // successful authentication if ($user->id) { // User already exists in database if (empty($user->auth)) { // For some reason auth isn't set yet $DB->set_field('user', 'auth', $auth, array('username'=>$username)); $user->auth = $auth; } update_internal_user_password($user, $password); // just in case salt or encoding were changed (magic quotes too one day) if ($authplugin->is_synchronised_with_external()) { // update user record from external DB $user = update_user_record($username); } } else { // Create account, we verified above that user creation is allowed. $user = create_user_record($username, $password, $auth); } $authplugin->sync_roles($user); foreach ($authsenabled as $hau) { $hauth = get_auth_plugin($hau); $hauth->user_authenticated_hook($user, $username, $password); } if (empty($user->id)) { return false; } if (!empty($user->suspended)) { // just in case some auth plugin suspended account add_to_log(SITEID, 'login', 'error', 'index.php', $username); error_log('[client '.getremoteaddr()."] $CFG->wwwroot Suspended Login: $username ".$_SERVER['HTTP_USER_AGENT']); return false; } return $user; } // failed if all the plugins have failed add_to_log(SITEID, 'login', 'error', 'index.php', $username); if (debugging('', DEBUG_ALL)) { error_log('[client '.getremoteaddr()."] $CFG->wwwroot Failed Login: $username ".$_SERVER['HTTP_USER_AGENT']); } return false; }
/** * Create a new account using simple registration data if available * * @access private * @param object &$resp An OpenID consumer response object * @return object The new user */ function _create_account(&$resp) { global $CFG, $USER; $url = $resp->identity_url; $password = hash_internal_user_password('openid'); $server = $resp->endpoint->server_url; $sreg_resp = Auth_OpenID_SRegResponse::fromSuccessResponse($resp); $sreg = $sreg_resp->contents(); // We'll attempt to use the user's nickname to set their username if (isset($sreg['nickname']) && !empty($sreg['nickname']) && !record_exists('users', 'username', $sreg['nickname'])) { $username = $sreg['nickname']; } else { $username = openid_normalize_url_as_username($url); } create_user_record($username, $password, 'openid'); $user = get_complete_user_data('username', $username); openid_append_url($user, $url); // SREG fullname if (isset($sreg['fullname']) && !empty($sreg['fullname'])) { $name = openid_parse_full_name($sreg['fullname']); $user->firstname = $name['first']; $user->lastname = $name['last']; } // SREG email if (isset($sreg['email']) && !empty($sreg['email']) && !record_exists('user', 'email', $sreg['email'])) { $user->email = $sreg['email']; } // SREG country if (isset($sreg['country']) && !empty($sreg['country'])) { $country = $sreg['country']; $country_code = strtoupper($country); $countries = get_list_of_countries(); if (strlen($country) != 2 || !isset($countries[$country_code])) { $countries_keys = array_keys($countries); $countries_vals = array_values($countries); $country_code = array_search($country, $countries_vals); if ($country_code > 0) { $country_code = $countries_keys[$country_code]; } else { $country_code = ''; } } if (!empty($country_code)) { $user->country = $country_code; } } /* We're currently not attempting to get language and timezone values // SREG language if (isset($sreg['language']) && !empty($sreg['language'])) { } // SREG timezone if (isset($sreg['timezone']) && !empty($sreg['timezone'])) { } */ if (function_exists('on_openid_create_account')) { on_openid_create_account($resp, $user); } update_record('user', $user); $user = get_complete_user_data('id', $user->id); // Redirect the user to their profile page if not set up properly if (!empty($user) && user_not_fully_set_up($user)) { $USER = clone $user; $urltogo = $CFG->wwwroot . '/user/edit.php'; redirect($urltogo); } return $user; }
/** * Auto-register a new user account for the current avatar. * NOTE: this does NOT respect ANYTHING but the most basic Moodle accounts. * Use at your own risk! * @return string|bool The new password (plaintext) if successful, or false if not * @access public */ function autoregister_avatar_user() { global $CFG; // Make sure we have avatar data, and reset the user data if (empty($this->avatar_data)) { return false; } $this->user_data = null; // Construct a basic username $nameparts = explode(' ', $this->avatar_data->avname); $baseusername = strip_tags(stripslashes(implode('', $nameparts))); $username = $baseusername; $conflict_moodle = record_exists('user', 'username', $username); // If that didn't work, then try a few random variants (just a number added to the end of the name) $MAX_RANDOM_TRIES = 3; $rnd_try = 0; while ($rnd_try < $MAX_RANDOM_TRIES && $conflict_moodle) { // Pick a random 3 digit number $rnd_num = mt_rand(100, 998); if ($rnd_num >= 666) { $rnd_num++; } // Some users may object to this number // Construct a new username to try $username = $baseusername . (string) $rnd_num; // Check for conflicts $conflict_moodle = record_exists('user', 'username', $username); // Next attempt $rnd_try++; } // Stop if we haven't found a unique name if ($conflict_moodle) { return false; } // Looks like we got an OK username // Generate a random password $plain_password = sloodle_random_web_password(); // Create the new user $this->user_data = create_user_record($username, $plain_password); if (!$this->user_data) { $this->user_data = null; return false; } // Get the complete user data again, so that we have the password this time //$this->user_data = get_complete_user_data('id', $this->user_data->id); // this should not be necessary $this->user_data = get_record('user', 'id', $this->user_data->id); // this should be sufficient // Attempt to use the first and last names of the avatar $this->user_data->firstname = $nameparts[0]; if (isset($nameparts[1])) { $this->user_data->lastname = $nameparts[1]; } else { $this->user_data->lastname = $nameparts[0]; } // Prevent emails from being sent to this user $this->user_data->emailstop = 1; // Attempt to update the database (we don't really care if this fails, since everything else will have worked) update_record('user', $this->user_data); // Now link the avatar to this account $this->avatar_data->userid = $this->user_data->id; update_record('sloodle_users', $this->avatar_data); return $plain_password; }
/** * @link http://docs.moodle.org/dev/Authentication_plugins#loginpage_hook.28.29 * * Hook for overriding behaviour of login page. * Another auth hook. Process login if $authorizationcode is defined in OAuth url. * Makes cURL POST/GET request to social webservice and fill response data to Moodle user. * We check access tokens in cookies, if the ones exists - get it from $_COOKIE, if no - setcookie * * @uses $SESSION, $CFG, $DB core global objects/variables * @return void or @moodle_exception if OAuth request returns error or fail * * @author Igor Sazonov ( @tigusigalpa ) */ function loginpage_hook() { global $SESSION, $CFG, $DB; $access_token = false; $authorizationcode = optional_param('oauthcode', '', PARAM_TEXT); // get authorization code from url if (!empty($authorizationcode)) { $authprovider = required_param('authprovider', PARAM_TEXT); // get authorization provider (webservice name) $hack_authprovider = $authprovider == 'yahoo1' || $authprovider == 'yahoo2' ? 'yahoo' : $authprovider; $config_field_str = 'auth_lenauth_' . $hack_authprovider . '_social_id_field'; $this->_field_shortname = $this->_oauth_config->{$config_field_str}; $this->_field_id = $this->_lenauth_get_fieldid(); $params = array(); // params to generate data for token request $encode_params = true; $code = true; $redirect_uri = true; $curl_header = false; $curl_options = array(); //if we have access_token in $_COOKIE, so do not need to make request fot the one $this->_send_oauth_request = !isset($_COOKIE[$authprovider]['access_token']) ? true : false; //if service is not enabled, why should we make request? hack protect. maybe $enabled_str = 'auth_lenauth_' . $hack_authprovider . '_enabled'; if (empty($this->_oauth_config->{$enabled_str})) { throw new moodle_exception('Service not enabled in your LenAuth Settings', 'auth_lenauth'); } switch ($authprovider) { case 'facebook': /** * @link https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.0#exchangecode */ $params['client_id'] = $this->_oauth_config->auth_lenauth_facebook_app_id; $params['client_secret'] = $this->_oauth_config->auth_lenauth_facebook_app_secret; break; case 'google': /** * @link https://developers.google.com/accounts/docs/OAuth2Login#exchangecode */ $params['client_id'] = $this->_oauth_config->auth_lenauth_google_client_id; $params['client_secret'] = $this->_oauth_config->auth_lenauth_google_client_secret; $params['grant_type'] = $this->_settings[$authprovider]['grant_type']; break; case 'yahoo1': if (!isset($_COOKIE[$authprovider]['access_token']) && !isset($_COOKIE[$authprovider]['oauth_verifier'])) { $params = array_merge($this->_lenauth_yahoo_request_array($this->_oauth_config->auth_lenauth_yahoo_consumer_secret . '&'), array('oauth_callback' => $this->_lenauth_redirect_uri($authprovider))); $code = false; $redirect_uri = false; $this->_send_oauth_request = isset($_REQUEST['oauth_token'], $_REQUEST['oauth_verifier']) ? false : true; $oauth_verifier = false; // yahoo =)) if (!$this->_send_oauth_request && isset($SESSION->yahoo_expires) && !empty($SESSION->yahoo_expires)) { $access_token = $SESSION->yahoo_access_token = optional_param('oauth_token', '', PARAM_TEXT); setcookie($authprovider . '[access_token]', $access_token, time() + $SESSION->yahoo_expires); $oauth_verifier = $SESSION->yahoo_oauth_verifier = optional_param('oauth_verifier', '', PARAM_TEXT); setcookie($authprovider . '[oauth_verifier]', $oauth_verifier, time() + $SESSION->yahoo_expires); } else { } } else { $this->_send_oauth_request = false; } break; case 'yahoo2': $params['grant_type'] = $this->_settings[$authprovider]['grant_type']; $curl_options = array('USERPWD' => $this->_oauth_config->auth_lenauth_yahoo_consumer_key . ':' . $this->_oauth_config->auth_lenauth_yahoo_consumer_secret); break; case 'twitter': if (!empty($this->_oauth_config->auth_lenauth_twitter_enabled)) { if (!isset($_COOKIE[$authprovider]['access_token'])) { $params = array_merge($this->_lenauth_twitter_request_array($this->_oauth_config->auth_lenauth_twitter_consumer_secret . '&'), array('oauth_callback' => $this->_lenauth_redirect_uri($authprovider))); $code = false; $redirect_uri = false; $this->_send_oauth_request = isset($_REQUEST['oauth_token'], $_REQUEST['oauth_verifier']) ? false : true; $oauth_verifier = false; if (!$this->_send_oauth_request && isset($_COOKIE[$authprovider]['oauth_token_secret'])) { $access_token = $SESSION->twitter_access_token = optional_param('oauth_token', '', PARAM_TEXT); setcookie($authprovider . '[access_token]', $access_token, time() + $this->_settings[$authprovider]['expire'], '/'); $oauth_verifier = $SESSION->twitter_oauth_verifier = optional_param('oauth_verifier', '', PARAM_TEXT); setcookie($authprovider . '[oauth_verifier]', $oauth_verifier, time() + $this->_settings[$authprovider]['expire'], '/'); } else { $curl_header = $this->_lenauth_set_twitter_header($params); } //$curl_header = $this->_lenauth_set_twitter_header($params, $access_token/*, $oauth_token_secret = false*/); /*$curl_options = array( 'CURLOPT_RETURNTRANSFER' => true, 'CURLOPT_FOLLOWLOCATION' => true ); if ( !empty( $params['oauth_callback'] ) ) { $curl_options['CURLOPT_POSTFIELDS'] = http_build_query( array() ); }*/ //TWITTER IS GOOD!! $encode_params = false; } else { $this->_send_oauth_request = false; } } break; case 'vk': /** * @link http://vk.com/dev/auth_sites */ $params['client_id'] = $this->_oauth_config->auth_lenauth_vk_app_id; $params['client_secret'] = $this->_oauth_config->auth_lenauth_vk_app_secret; break; case 'yandex': $params['grant_type'] = $this->_settings[$authprovider]['grant_type']; $params['client_id'] = $this->_oauth_config->auth_lenauth_yandex_app_id; $params['client_secret'] = $this->_oauth_config->auth_lenauth_yandex_app_password; break; case 'mailru': $params['client_id'] = $this->_oauth_config->auth_lenauth_mailru_site_id; $params['client_secret'] = $this->_oauth_config->auth_lenauth_mailru_client_secret; $params['grant_type'] = $this->_settings[$authprovider]['grant_type']; break; //odnoklassniki.ru was wrote by school programmers at 1st class and it not used mojority. bye-bye! /*case 'ok': $params['client_id'] = $this->_oauth_config->ok_app_id; $params['client_secret'] = $this->_oauth_config->ok_secret_key; break;*/ //odnoklassniki.ru was wrote by school programmers at 1st class and it not used mojority. bye-bye! /*case 'ok': $params['client_id'] = $this->_oauth_config->ok_app_id; $params['client_secret'] = $this->_oauth_config->ok_secret_key; break;*/ default: // if authorization provider is wrong throw new moodle_exception('Unknown OAuth Provider', 'auth_lenauth'); } // url for catch token value // exception for Yahoo OAuth, because it like.. if ($code) { $params['code'] = $authorizationcode; } if ($redirect_uri) { $params['redirect_uri'] = $this->_lenauth_redirect_uri($authprovider); } //require cURL from Moodle core require_once $CFG->libdir . '/filelib.php'; // requires library with cURL class $curl = new curl(); //hack for twitter and Yahoo if (!empty($curl_options) && is_array($curl_options)) { $curl->setopt($curl_options); } $curl->resetHeader(); // clean cURL header from garbage //Twitter and Yahoo has an own cURL headers, so let them to be! if (!$curl_header) { $curl->setHeader('Content-Type: application/x-www-form-urlencoded'); } else { $curl->setHeader($curl_header); } // cURL REQUEST for tokens if we hasnt it in $_COOKIE if ($this->_send_oauth_request) { if ($this->_curl_type == 'post') { $curl_tokens_values = $curl->post($this->_settings[$authprovider]['request_token_url'], $encode_params ? $this->_generate_query_data($params) : $params); } else { $curl_tokens_values = $curl->get($this->_settings[$authprovider]['request_token_url'] . '?' . ($encode_params ? $this->_generate_query_data($params) : $params)); } } // check for token response if (!empty($curl_tokens_values) || !$this->_send_oauth_request) { $token_values = array(); // parse token values switch ($authprovider) { case 'facebook': if ($this->_send_oauth_request || !isset($_COOKIE[$authprovider]['access_token'])) { parse_str($curl_tokens_values, $token_values); $expires = $token_values['expires']; //5183999 = 2 months $access_token = $token_values['access_token']; if (!empty($expires) && !empty($access_token)) { setcookie($authprovider . '[access_token]', $access_token, time() + $expires, '/'); } else { throw new moodle_exception('Can not get access for "access_token" or/and "expires" params after request', 'auth_lenauth'); } } else { if (isset($_COOKIE[$authprovider]['access_token'])) { $access_token = $_COOKIE[$authprovider]['access_token']; } else { throw new moodle_exception('Someting wrong, maybe expires', 'auth_lenauth'); } } break; case 'google': if ($this->_send_oauth_request || !isset($_COOKIE[$authprovider]['access_token'])) { $token_values = json_decode($curl_tokens_values, true); $expires = $token_values['expires_in']; //3600 = 1 hour $access_token = $token_values['access_token']; if (!empty($access_token) && !empty($expires)) { setcookie($authprovider . '[access_token]', $access_token, time() + $expires, '/'); } else { throw new moodle_exception('Can not get access for "access_token" or/and "expires" params after request', 'auth_lenauth'); } } else { if (isset($_COOKIE[$authprovider]['access_token'])) { $access_token = $_COOKIE[$authprovider]['access_token']; } else { throw new moodle_exception('Someting wrong, maybe expires', 'auth_lenauth'); } } break; case 'yahoo1': if ($this->_send_oauth_request || !isset($_COOKIE[$authprovider]['oauth_token_secret'])) { parse_str($curl_tokens_values, $token_values); $expires = $SESSION->yahoo_expires = $token_values['oauth_expires_in']; //3600 = 1 hour $access_token = $SESSION->yahoo_access_token = $token_values['oauth_token']; setcookie($authprovider . '[oauth_token_secret]', $token_values['oauth_token_secret'], time() + $SESSION->yahoo_expires); $xoauth_request_auth_url = $token_values['xoauth_request_auth_url']; } else { if (isset($_COOKIE[$authprovider]['access_token'], $_COOKIE[$authprovider]['oauth_verifier']) || isset($SESSION->yahoo_access_token, $SESSION->yahoo_oauth_verifier)) { $access_token = isset($_COOKIE[$authprovider]['access_token']) ? $_COOKIE[$authprovider]['access_token'] : $SESSION->yahoo_access_token; $oauth_verifier = isset($_COOKIE[$authprovider]['oauth_verifier']) ? $_COOKIE[$authprovider]['oauth_verifier'] : $SESSION->yahoo_oauth_verifier; } else { throw new moodle_exception('Someting wrong, maybe expires', 'auth_lenauth'); } } break; case 'yahoo2': if ($this->_send_oauth_request || !isset($_COOKIE[$authprovider]['access_token'])) { $token_values = json_decode($curl_tokens_values, true); $expires = $token_values['expires_in']; //3600 = 1 hour $access_token = $token_values['access_token']; $refresh_token = $token_values['refresh_token']; $user_id = $token_values['xoauth_yahoo_guid']; if (!empty($expires) && !empty($access_token)) { setcookie($authprovider . '[access_token]', $access_token, time() + $expires, '/'); if (!empty($user_id)) { setcookie($authprovider . '[user_id]', $user_id, time() + $expires, '/'); } } else { throw new moodle_exception('Can not get access for "access_token" or/and "expires" params after request', 'auth_lenauth'); } } else { if (isset($_COOKIE[$authprovider]['access_token'], $_COOKIE[$authprovider]['user_id'])) { $access_token = $_COOKIE[$authprovider]['access_token']; $user_id = $_COOKIE[$authprovider]['user_id']; } else { throw new moodle_exception('Someting wrong, maybe expires', 'auth_lenauth'); } } break; case 'twitter': if ($this->_send_oauth_request || !isset($_COOKIE[$authprovider]['oauth_token_secret'])) { parse_str($curl_tokens_values, $token_values); $access_token = $SESSION->twitter_access_token = $token_values['oauth_token']; setcookie($authprovider . '[oauth_token_secret]', $token_values['oauth_token_secret'], time() + $this->_settings[$authprovider]['expire'], '/'); } else { if (isset($_COOKIE[$authprovider]['access_token'], $_COOKIE[$authprovider]['oauth_token_secret']) || isset($SESSION->twitter_access_token, $SESSION->twitter_oauth_verifier)) { $access_token = isset($_COOKIE[$authprovider]['access_token']) ? $_COOKIE[$authprovider]['access_token'] : $SESSION->twitter_access_token; $oauth_verifier = isset($_COOKIE[$authprovider]['oauth_verifier']) ? $_COOKIE[$authprovider]['oauth_verifier'] : $SESSION->twitter_oauth_verifier; } else { throw new moodle_exception('Someting wrong, maybe expires', 'auth_lenauth'); } } break; case 'vk': if ($this->_send_oauth_request || !isset($_COOKIE[$authprovider]['access_token'])) { $token_values = json_decode($curl_tokens_values, true); if (isset($token_values['error'])) { throw new moodle_exception('Native VK Error ' . $token_values['error'] . (isset($token_values['error_description']) ? ' with description: ' . $token_values['error_description'] : ''), 'auth_lenauth'); } $expires = $token_values['expires_in']; //86400 = 24 hours $access_token = $token_values['access_token']; if (!empty($access_token) && !empty($expires)) { setcookie($authprovider . '[access_token]', $access_token, time() + $expires, '/'); } $user_id = $token_values['user_id']; if (!empty($user_id)) { setcookie($authprovider . '[user_id]', $user_id, time() + $expires, '/'); } /** * VK user may do not enter email, soooo =(( */ $user_email = isset($token_values['email']) ? $token_values['email'] : false; // WOW!!! So early???))) Awesome! if (!empty($user_email)) { setcookie($authprovider . '[user_email]', $user_email, time() + $expires, '/'); } } else { if (isset($_COOKIE[$authprovider]['access_token'], $_COOKIE[$authprovider]['user_id'])) { $access_token = $_COOKIE[$authprovider]['access_token']; $user_id = $_COOKIE[$authprovider]['user_id']; if (isset($_COOKIE[$authprovider]['user_email'])) { $user_email = $_COOKIE[$authprovider]['user_email']; } } else { throw new moodle_exception('Someting wrong, maybe expires', 'auth_lenauth'); } } break; case 'yandex': if ($this->_send_oauth_request || !isset($_COOKIE[$authprovider]['access_token'])) { $token_values = json_decode($curl_tokens_values, true); $expires = $token_values['expires_in']; //31536000 = 1 year $access_token = $token_values['access_token']; if (!empty($expires) && !empty($access_token)) { setcookie($authprovider . '[access_token]', $access_token, time() + $expires, '/'); } else { throw new moodle_exception('Can not get access for "access_token" or/and "expires" params after request', 'auth_lenauth'); } } else { if (isset($_COOKIE[$authprovider]['access_token'])) { $access_token = $_COOKIE[$authprovider]['access_token']; } else { throw new moodle_exception('Someting wrong, maybe expires', 'auth_lenauth'); } } break; case 'mailru': if ($this->_send_oauth_request || !isset($_COOKIE[$authprovider]['access_token'])) { $token_values = json_decode($curl_tokens_values, true); $expires = $token_values['expires_in']; //86400 = 24 hours $access_token = $token_values['access_token']; if (!empty($expires) && !empty($access_token)) { setcookie($authprovider . '[access_token]', $access_token, time() + $expires, '/'); } else { //check native errors if exists if (isset($token_values['error'])) { switch ($token_values['error']) { case 'invalid_client': throw new moodle_exception('Mail.RU invalid OAuth settings. Check your Private Key and Secret Key', 'auth_lenauth'); default: throw new moodle_exception('Mail.RU Unknown Error with code: ' . $token_values['error']); } } if (empty($expires) || empty($access_token)) { throw new moodle_exception('Can not get access for "access_token" or/and "expires" params after request', 'auth_lenauth'); } } } else { if (isset($_COOKIE[$authprovider]['access_token'])) { $access_token = $_COOKIE[$authprovider]['access_token']; } else { throw new moodle_exception('Someting wrong, maybe expires', 'auth_lenauth'); } } break; /*case 'ok': $token_values = json_decode( $curl_tokens_values, true ); $access_token = $token_values['access_token']; break;*/ /*case 'ok': $token_values = json_decode( $curl_tokens_values, true ); $access_token = $token_values['access_token']; break;*/ default: throw new moodle_exception('Unknown OAuth Provider', 'auth_lenauth'); } } if (!empty($access_token)) { $queryparams = array(); // array to generate data for final request to get user data $request_api_url = $this->_settings[$authprovider]['request_api_url']; //some services check accounts for verifier, so we will check it too. No unverified accounts, only verified! only hardCORE! $is_verified = true; $image_url = ''; switch ($authprovider) { case 'facebook': $queryparams['access_token'] = $access_token; $curl_response = $curl->get($request_api_url . '?' . $this->_generate_query_data($queryparams)); $curl_final_data = json_decode($curl_response, true); $social_uid = $curl_final_data['id']; $user_email = $curl_final_data['email']; $first_name = $curl_final_data['first_name']; $last_name = $curl_final_data['last_name']; $is_verified = $curl_final_data['verified']; if ($this->_oauth_config->auth_lenauth_retrieve_avatar) { $image_url = 'http://graph.facebook.com/' . $social_uid . '/picture'; } break; /** * @link https://developers.google.com/accounts/docs/OAuth2Login#obtaininguserprofileinformation */ /** * @link https://developers.google.com/accounts/docs/OAuth2Login#obtaininguserprofileinformation */ case 'google': $queryparams['access_token'] = $access_token; $queryparams['alt'] = 'json'; $curl_response = $curl->get($request_api_url . '?' . $this->_generate_query_data($queryparams)); $curl_final_data = json_decode($curl_response, true); if (isset($curl_final_data['error'])) { if (!empty($curl_final_data['error']['errors']) && is_array($curl_final_data['error']['errors'])) { foreach ($curl_final_data['error']['errors'] as $error) { throw new moodle_exception('Native Google error. Message: ' . $error['message'], 'auth_lenauth'); } } else { throw new moodle_exception('Native Google error', 'auth_lenauth'); } } $social_uid = $curl_final_data['id']; $user_email = $curl_final_data['emails'][0]['value']; $first_name = $curl_final_data['name']['givenName']; $last_name = $curl_final_data['name']['familyName']; if ($this->_oauth_config->auth_lenauth_retrieve_avatar) { $image_url = isset($curl_final_data['image']['url']) ? $curl_final_data['image']['url'] : ''; } break; case 'yahoo1': if (!$oauth_verifier) { header('Location: ' . $xoauth_request_auth_url); // yahoo =)) die; } $queryparams1 = array_merge($this->_lenauth_yahoo_request_array($this->_oauth_config->auth_lenauth_yahoo_consumer_secret . '&' . $_COOKIE[$authprovider]['oauth_token_secret']), array('oauth_token' => $access_token, 'oauth_verifier' => $oauth_verifier)); $curl_response_pre = $curl->get($request_api_url . '?' . $this->_generate_query_data($queryparams1)); parse_str($curl_response_pre, $values); $queryparams2 = array_merge($this->_lenauth_yahoo_request_array($this->_oauth_config->auth_lenauth_yahoo_consumer_secret . '&' . $values['oauth_token_secret']), array('oauth_token' => $values['oauth_token'], 'oauth_session_handle' => $values['oauth_session_handle'])); $yet_another = $curl->post($request_api_url . '?' . $this->_generate_query_data($queryparams2)); parse_str($yet_another, $yet_another_values); $params = array('q' => 'SELECT * FROM social.profile where guid="' . $yet_another_values['xoauth_yahoo_guid'] . '"', 'format' => 'json', 'env' => 'http://datatables.org/alltables.env'); $auth_array = array_merge($this->_lenauth_yahoo_request_array($this->_oauth_config->auth_lenauth_yahoo_consumer_secret . '&' . $yet_another_values['oauth_token_secret']), array('realm' => 'yahooapis.com', 'oauth_token' => $yet_another_values['oauth_token'])); $header = ''; foreach ($auth_array as $key => $value) { $header .= ($header === '' ? ' ' : ',') . $this->urlEncodeRfc3986($key) . '="' . $this->urlEncodeRfc3986($value) . '"'; } $curl->setHeader(array('Expect:', 'Accept: application/json', 'Authorization: OAuth ' . $header)); $curl_response = $curl->post($this->_settings[$authprovider]['yql_url'] . '?' . $this->_generate_query_data($params)); $curl_final_data = json_decode($curl_response, true); $social_uid = $curl_final_data['query']['results']['profile']['guid']; $emails = $curl_final_data['query']['results']['profile']['emails']; if (!empty($emails) && is_array($emails)) { foreach ($emails as $email_array) { $user_email = $email_array['handle']; if (isset($email_array['primary'])) { break; } } } $first_name = $curl_final_data['query']['results']['profile']['givenName']; $last_name = $curl_final_data['query']['results']['profile']['familyName']; if ($this->_oauth_config->auth_lenauth_retrieve_avatar) { $image_url = isset($curl_final_data['query']['results']['profile']['image']['imageUrl']) ? $curl_final_data['query']['results']['profile']['image']['imageUrl'] : ''; } break; case 'yahoo2': $request_api_url = 'https://social.yahooapis.com/v1/user/' . $user_id . '/profile?format=json'; $queryparams['access_token'] = $access_token; $now_header = array('Authorization: Bearer ' . $access_token, 'Accept: application/json', 'Content-Type: application/json'); $curl->resetHeader(); $curl->setHeader($now_header); $curl_response = $curl->get($request_api_url, $queryparams); $curl->resetHeader(); $curl_final_data = json_decode($curl_response, true); $social_uid = $curl_final_data['profile']['guid']; $emails = $curl_final_data['profile']['emails']; if (!empty($emails) && is_array($emails)) { foreach ($emails as $email_array) { $user_email = $email_array['handle']; if (isset($email_array['primary'])) { break; } } } $first_name = $curl_final_data['profile']['givenName']; $last_name = $curl_final_data['profile']['familyName']; if ($this->_oauth_config->auth_lenauth_retrieve_avatar) { $image_url = isset($curl_final_data['profile']['image']['imageUrl']) ? $curl_final_data['profile']['image']['imageUrl'] : ''; } break; case 'twitter': if (!$oauth_verifier) { header('Location: ' . $this->_settings[$authprovider]['request_api_url'] . '?' . http_build_query(array('oauth_token' => $access_token))); die; } $queryparams = array_merge($this->_lenauth_twitter_request_array(), array('oauth_verifier' => $oauth_verifier, 'oauth_token' => $access_token, 'oauth_token_secret' => $_COOKIE[$authprovider]['oauth_token_secret'])); $curl_header = $this->_lenauth_set_twitter_header($queryparams, $access_token, $_COOKIE[$authprovider]['oauth_token_secret']); $curl->setHeader($curl_header); $curl_final_data_pre = $curl->post($this->_settings[$authprovider]['token_url'], $queryparams); $json_decoded = json_decode($curl_final_data_pre, true); if (isset($json_decoded['error']) && isset($json_decoded['request'])) { throw new moodle_exception('Native Twitter Error: ' . $json_decoded['error'] . '. For request ' . $json_decoded['request'], 'auth_lenauth'); } parse_str($curl_final_data_pre, $curl_final_data); $social_uid = $curl_final_data['user_id']; if ($this->_oauth_config->auth_lenauth_retrieve_avatar) { $image_url_pre = 'https://twitter.com/' . $curl_final_data['screen_name'] . '/profile_image?size=original'; $image_header = get_headers($image_url_pre, 1); $image_url = $image_header['location']; } break; case 'vk': /** * @link http://vk.com/dev/api_requests */ $queryparams['access_token'] = $access_token; $queryparams['user_id'] = !empty($user_id) ? $user_id : false; $queryparams['v'] = self::$vk_api_version; $curl_response = $curl->post($request_api_url, $this->_generate_query_data($queryparams)); $curl_final_data = json_decode($curl_response, true); //$social_uid = ( isset( $user_id ) ) ? $user_id : $curl_final_data['response'][0]['id']; //dont forget about this $social_uid = $queryparams['user_id']; /** * If user_email is empty, its not so scare, because its second login and */ $user_email = isset($user_email) ? $user_email : false; //hack, because VK has bugs sometimes $first_name = $curl_final_data['response'][0]['first_name']; $last_name = $curl_final_data['response'][0]['last_name']; /** * @link http://vk.com/dev/users.get */ $fields_array = array('avatar' => 'photo_200'); $additional_fields_pre = $curl->get('http://api.vk.com/method/users.get?user_ids=' . $social_uid . '&fields=' . join(',', $fields_array)); $additional_fields = json_decode($additional_fields_pre, true); if ($this->_oauth_config->auth_lenauth_retrieve_avatar) { $image_url = isset($additional_fields['response'][0][$fields_array['avatar']]) ? $additional_fields['response'][0][$fields_array['avatar']] : ''; } break; /** * @link http://api.yandex.ru/oauth/doc/dg/reference/accessing-protected-resource.xml * @link http://api.yandex.ru/login/doc/dg/reference/request.xml */ /** * @link http://api.yandex.ru/oauth/doc/dg/reference/accessing-protected-resource.xml * @link http://api.yandex.ru/login/doc/dg/reference/request.xml */ case 'yandex': $queryparams['format'] = $this->_settings[$authprovider]['format']; $queryparams['oauth_token'] = $access_token; $curl_response = $curl->get($request_api_url . '?' . $this->_generate_query_data($queryparams)); $curl_final_data = json_decode($curl_response, true); $social_uid = $curl_final_data['id']; /** * fix @since 24.12.2014. Thanks for Yandex Tech team guys!! * @link https://tech.yandex.ru/passport/ */ $user_email = $curl_final_data['default_email']; //was $curl_final_data['emails'][0]; - wrong! $first_name = $curl_final_data['first_name']; $last_name = $curl_final_data['last_name']; $nickname = $curl_final_data['display_name']; //for future if ($this->_oauth_config->auth_lenauth_retrieve_avatar) { /** * @link https://tech.yandex.ru/passport/doc/dg/reference/response-docpage/#norights_5 */ $yandex_avatar_size = 'islands-200'; if (isset($curl_final_data['default_avatar_id'])) { $image_url = 'https://avatars.yandex.net/get-yapic/' . $curl_final_data['default_avatar_id'] . '/' . $yandex_avatar_size; } } break; case 'mailru': $queryparams['app_id'] = $params['client_id']; $secret_key = $params['client_secret']; /** * @link http://api.mail.ru/docs/reference/rest/users-getinfo/ */ $queryparams['method'] = 'users.getInfo'; $queryparams['session_key'] = $access_token; $queryparams['secure'] = 1; /** * Additional security from mail.ru * @link http://api.mail.ru/docs/guides/restapi/#sig */ ksort($queryparams); $sig = ''; foreach ($queryparams as $k => $v) { $sig .= "{$k}={$v}"; } $queryparams['sig'] = md5($sig . $secret_key); $curl_response = $curl->post($request_api_url, $this->_generate_query_data($queryparams)); $curl_final_data = json_decode($curl_response, true); $social_uid = $curl_final_data[0]['uid']; $user_email = $curl_final_data[0]['email']; $first_name = $curl_final_data[0]['first_name']; $last_name = $curl_final_data[0]['last_name']; $is_verified = $curl_final_data[0]['is_verified']; $birthday = $curl_final_data[0]['birthday']; //dd.mm.YYYY if ($this->_oauth_config->auth_lenauth_retrieve_avatar) { $image_url = isset($curl_final_data[0]['pic_big']) ? $curl_final_data[0]['pic_big'] : ''; } break; /*case 'ok': $queryparams['access_token'] = $access_token; $queryparams['method'] = 'users.getCurrentUser'; $queryparams['sig'] = md5( 'application_key=' . $this->_oauth_config->ok_public_key . 'method=' . $queryparams['method'] . md5( $queryparams['access_token'] . $this->_oauth_config->ok_secret_key ) ); $queryparams['application_key'] = $this->_oauth_config->ok_public_key; $curl_response = $curl->get( $request_api_url . '?' . $this->_generate_query_data( $queryparams ) ); $curl_final_data = json_decode( $curl_response, true ); $first_name = $curl_final_data['first_name']; $last_name = $curl_final_data['last_name']; $social_uid = $curl_final_data['uid']; break;*/ /*case 'ok': $queryparams['access_token'] = $access_token; $queryparams['method'] = 'users.getCurrentUser'; $queryparams['sig'] = md5( 'application_key=' . $this->_oauth_config->ok_public_key . 'method=' . $queryparams['method'] . md5( $queryparams['access_token'] . $this->_oauth_config->ok_secret_key ) ); $queryparams['application_key'] = $this->_oauth_config->ok_public_key; $curl_response = $curl->get( $request_api_url . '?' . $this->_generate_query_data( $queryparams ) ); $curl_final_data = json_decode( $curl_response, true ); $first_name = $curl_final_data['first_name']; $last_name = $curl_final_data['last_name']; $social_uid = $curl_final_data['uid']; break;*/ default: throw new moodle_exception('Unknown OAuth Provider', 'auth_lenauth'); } /** * Check for email returned by webservice. If exist - check for user with this email in Moodle Database */ if (!empty($curl_final_data)) { if (!empty($social_uid)) { if ($is_verified) { if (!empty($user_email)) { if ($err = email_is_not_allowed($user_email)) { throw new moodle_exception($err, 'auth_lenauth'); } $user_lenauth = $DB->get_record('user', array('email' => $user_email, 'deleted' => 0, 'mnethostid' => $CFG->mnet_localhost_id)); } else { if (empty($user_lenauth)) { $user_lenauth = $this->_lenauth_get_userdata_by_social_id($social_uid); } /*if ( empty( $user_lenauth ) ) { $user_lenauth = $DB->get_record('user', array('username' => $username, 'deleted' => 0, 'mnethostid' => $CFG->mnet_localhost_id)); }*/ } } else { throw new moodle_exception('Your social account is not verified', 'auth_lenauth'); } } else { throw new moodle_exception('Empty Social UID', 'auth_lenauth'); } } else { /** * addon @since 24.12.2014 * I forgot about clear $_COOKIE, thanks again for Yandex Tech Team guys!!! */ @setcookie($authprovider, null, time() - 3600); throw new moodle_exception('Final request returns nothing', 'auth_lenauth'); } $last_user_number = intval($this->_oauth_config->auth_lenauth_last_user_number); $last_user_number = empty($last_user_number) ? 1 : $last_user_number + 1; //$username = $this->_oauth_config->auth_lenauth_user_prefix . $last_user_number; //@todo /** * If user with email from webservice not exists, we will create an account */ if (empty($user_lenauth)) { $username = $this->_oauth_config->auth_lenauth_user_prefix . $last_user_number; //check for username exists in DB $user_lenauth_check = $DB->get_record('user', array('username' => $username)); $i_check = 0; while (!empty($user_lenauth_check)) { $user_lenauth_check = $user_lenauth_check + 1; $username = $this->_oauth_config->auth_lenauth_user_prefix . $last_user_number; $user_lenauth_check = $DB->get_record('user', array('username' => $username)); $i_check++; if ($i_check > 20) { throw new moodle_exception('Something wrong with usernames of LenAuth users. Limit of 20 queries is out. Check last mdl_user table of Moodle', 'auth_lenauth'); } } // create user HERE $user_lenauth = create_user_record($username, '', 'lenauth'); /** * User exists... */ } else { $username = $user_lenauth->username; } set_config('auth_lenauth_last_user_number', $last_user_number, 'auth/lenauth'); if (!empty($social_uid)) { $user_social_uid_custom_field = new stdClass(); $user_social_uid_custom_field->userid = $user_lenauth->id; $user_social_uid_custom_field->fieldid = $this->_field_id; $user_social_uid_custom_field->data = $social_uid; if (!$DB->record_exists('user_info_data', array('userid' => $user_lenauth->id, 'fieldid' => $this->_field_id))) { $DB->insert_record('user_info_data', $user_social_uid_custom_field); } else { $record = $DB->get_record('user_info_data', array('userid' => $user_lenauth->id, 'fieldid' => $this->_field_id)); $user_social_uid_custom_field->id = $record->id; $DB->update_record('user_info_data', $user_social_uid_custom_field); } } //add_to_log( SITEID, 'auth_lenauth', '', '', $username . '/' . $user_email . '/' . $userid ); // complete Authenticate user authenticate_user_login($username, null); // fill $newuser object with response data from webservices $newuser = new stdClass(); if (!empty($user_email)) { $newuser->email = $user_email; } if (!empty($first_name)) { $newuser->firstname = $first_name; } if (!empty($last_name)) { $newuser->lastname = $last_name; } if (!empty($this->_oauth_config->auth_lenauth_default_country)) { $newuser->country = $this->_oauth_config->auth_lenauth_default_country; } if ($user_lenauth) { // update user record if (!empty($newuser)) { $newuser->id = $user_lenauth->id; /*require_once( $CFG->libdir . '/gdlib.php' ); $fs = get_file_storage(); $file_obj = $fs->create_file_from_url( array( 'contextid' => context_user::instance( $newuser->id, MUST_EXIST )->id, 'component' => 'user', 'filearea' => 'icon', 'itemid' => 0, 'filepath' => '/', 'source' => '', 'filename' => 'f' . $newuser->id . '.' . $ext ), $image_url ); //$newuser->picture = $file_obj->get_id();*/ $user_lenauth = (object) array_merge((array) $user_lenauth, (array) $newuser); $DB->update_record('user', $user_lenauth); if ($this->_oauth_config->auth_lenauth_retrieve_avatar) { //processing user avatar from social webservice if (!empty($image_url) && intval($user_lenauth->picture) === 0) { $image_header = get_headers($image_url, 1); if (isset($image_header['Content-Type']) && is_string($image_header['Content-Type']) && in_array($image_header['Content-Type'], array_keys(self::$_allowed_icons_types))) { $mime = $image_header['Content-Type']; } else { if (isset($image_header['Content-Type'][0]) && is_string($image_header['Content-Type'][0]) && in_array($image_header['Content-Type'][0], array_keys(self::$_allowed_icons_types))) { $mime = $image_header['Content-Type'][0]; } } $ext = $this->_lenauth_get_image_extension_from_mime($mime); if ($ext) { //create temp file $tempfilename = substr(microtime(), 0, 10) . '.tmp'; $templfolder = $CFG->tempdir . '/filestorage'; if (!file_exists($templfolder)) { mkdir($templfolder, $CFG->directorypermissions); } @chmod($templfolder, 0777); $tempfile = $templfolder . '/' . $tempfilename; if (copy($image_url, $tempfile)) { require_once $CFG->libdir . '/gdlib.php'; $usericonid = process_new_icon(context_user::instance($newuser->id, MUST_EXIST), 'user', 'icon', 0, $tempfile); if ($usericonid) { $DB->set_field('user', 'picture', $usericonid, array('id' => $newuser->id)); } unset($tempfile); } @chmod($templfolder, $CFG->directorypermissions); } } } } complete_user_login($user_lenauth); // complete user login // Redirection $urltogo = $CFG->wwwroot; if (user_not_fully_set_up($user_lenauth)) { $urltogo = $CFG->wwwroot . '/user/edit.php'; } else { if (isset($SESSION->wantsurl) && strpos($SESSION->wantsurl, $CFG->wwwroot) === 0) { $urltogo = $SESSION->wantsurl; unset($SESSION->wantsurl); } else { unset($SESSION->wantsurl); } } } redirect($urltogo); } else { throw new moodle_exception('Could not get access to access token. Check your App Settings', 'auth_lenauth'); } } }
/** * This function gets test user from DB user table or creates the test user if it doesn't already exist * @param string $username Optional username for test user (defaults to 'testuser') * @param string $email Optional email address for test user (defaults to '*****@*****.**') * @return object The testuser object or false on error. */ function get_test_user($username = '', $email = '') { global $DB, $CFG; if ($username === '') { $username = '******'; } $testuser = $DB->get_record('user', array('username' => $username)); if (empty($testuser)) { $testuser = new stdClass(); $testuser->username = $username; $testuser->password = md5('Test1234!'); $testuser->mnethostid = $CFG->mnet_localhost_id; $testuser = create_user_record($testuser->username, $testuser->password); if (empty($testuser)) { return false; } // Setup fields to get thru: require_login(). $testuser->firstname = 'Test'; $testuser->lastname = 'User'; if (empty($email)) { $email = "{$username}@example.com"; } $testuser->email = $email; $testuser->confirmed = true; $testuser->deleted = false; $testuser->country = 'CA'; $testuser->city = 'Waterloo'; } $testuser->deleted = false; $DB->update_record('user', $testuser); return $testuser; }
/** * Authentication hook - is called every time user hit the login page * The code is run only if the param code is mentionned. */ function loginpage_hook() { global $SESSION, $CFG, $DB, $USER; $authorizationcode = optional_param('code', '', PARAM_TEXT); if (!empty($authorizationcode) && 200 == $authorizationcode) { require_once $CFG->dirroot . '/auth/oauth_simple/lib.php'; $cfg = get_config('auth/oauth_simple'); $accesstoken = $SESSION->access_token; $connection = new TwitterOAuth($cfg->apiurl, $cfg->baseurl, $cfg->consumer_key, $cfg->consumer_secret, $accesstoken['oauth_token'], $accesstoken['oauth_token_secret']); $userinfo = $connection->post($cfg->apifunc); if (!empty($userinfo->{$cfg->username})) { $user = $DB->get_record('user', array('username' => $userinfo->{$cfg->username}, 'deleted' => 0, 'mnethostid' => $CFG->mnet_localhost_id)); // Create the user if it doesn't exist. if (empty($user)) { // Deny login if setting "Prevent account creation when authenticating" is on. if ($CFG->authpreventaccountcreation) { throw new moodle_exception("noaccountyet", "auth_oauth_simple"); } $username = $userinfo->{$cfg->username}; create_user_record($username, '', 'oauth_simple'); } else { $username = $user->username; } // Authenticate the user. $userid = empty($user) ? 'new user' : $user->id; add_to_log(SITEID, 'auth_oauth_simple', '', '', $username . '/' . $userid); $user = authenticate_user_login($username, null); if ($user) { // if (!empty($newuser)) { // $newuser->id = $user->id; // $newuser->id = $user->id; // $DB->update_record('user', $newuser); $DB->update_record('user', $user); // $user = (object) array_merge((array) $user, (array) $newuser); // } complete_user_login($user); // Create event for authenticated user. $event = \auth_oauth_simple\event\user_loggedin::create(array('context' => context_system::instance(), 'objectid' => $user->id, 'relateduserid' => $user->id, 'other' => array('accesstoken' => $accesstoken))); $event->trigger(); // Redirection. if (user_not_fully_set_up($USER)) { $urltogo = $CFG->wwwroot . '/user/edit.php'; // We don't delete $SESSION->wantsurl yet, so we get there later. } else { if (isset($SESSION->wantsurl) and strpos($SESSION->wantsurl, $CFG->wwwroot) === 0) { $urltogo = $SESSION->wantsurl; // Because it's an address in this site. unset($SESSION->wantsurl); } else { // No wantsurl stored or external - go to homepage. $urltogo = $CFG->wwwroot . '/'; unset($SESSION->wantsurl); } } redirect($urltogo); } } else { throw new moodle_exception('invalid access', 'auth_oauth_simple'); } } }
function turnitintool_restore_mods($mod, $restore) { global $CFG, $DB; $status = true; $data = backup_getid($restore->backup_unique_code, $mod->modtype, $mod->id); if ($data) { $info = $data->info; // Recreate the turnitintool_course entries $course = new stdClass(); $course->id = backup_todb($info['MOD']['#']['COURSE']['0']['#']['ID']['0']['#']); $course->courseid = backup_todb($info['MOD']['#']['COURSE']['0']['#']['COURSEID']['0']['#']); $course->ownerid = backup_todb($info['MOD']['#']['COURSE']['0']['#']['OWNERID']['0']['#']); $course->turnitin_ctl = backup_todb($info['MOD']['#']['COURSE']['0']['#']['TURNITIN_CTL']['0']['#']); $course->turnitin_cid = backup_todb($info['MOD']['#']['COURSE']['0']['#']['TURNITIN_CID']['0']['#']); $course->ownertiiuid = backup_todb($info['MOD']['#']['COURSE']['0']['#']['OWNERTIIUID']['0']['#']); $course->ownerfn = backup_todb($info['MOD']['#']['COURSE']['0']['#']['OWNERFN']['0']['#']); $course->ownerln = backup_todb($info['MOD']['#']['COURSE']['0']['#']['OWNERLN']['0']['#']); $course->ownerun = backup_todb($info['MOD']['#']['COURSE']['0']['#']['OWNERUN']['0']['#']); $course->owneremail = backup_todb($info['MOD']['#']['COURSE']['0']['#']['OWNEREMAIL']['0']['#']); $tiicourseid = $course->turnitin_cid; // Determine if the destination course already has a TII Class associated, add check to determine the database call to enable backward compatibility // if it does is it the same class as the one we are restoring if (is_callable(array($DB, 'get_records_select'))) { $tiicourses = $DB->get_records_select('turnitintool_courses', 'turnitin_cid=' . $tiicourseid . ' OR courseid=' . $restore->course_id, null, "courseid", "id,courseid,turnitin_cid"); } else { $tiicourses = get_records_select('turnitintool_courses', 'turnitin_cid=' . $tiicourseid . ' OR courseid=' . $restore->course_id, "courseid", "id,courseid,turnitin_cid"); } $tiicourses = !$tiicourses ? array() : $tiicourses; $backupaccountid = $info['MOD']['#']['TIIACCOUNT']['0']['#']; if ($CFG->turnitin_account_id != $backupaccountid) { if (!defined('RESTORE_SILENTLY')) { // Course Error $input = new stdClass(); $input->current = !empty($CFG->turnitin_account_id) ? $CFG->turnitin_account_id : '(' . get_string("notavailableyet", "turnitintool") . ')'; $input->backupid = $backupaccountid; echo "<li class=\"error\">" . get_string("modulename", "turnitintool") . " : " . get_string("wrongaccountid", "turnitintool", $input) . "\"</li>"; } return true; // Don't exit restore on failure... } $restorable = true; $thiscourse = false; foreach ($tiicourses as $tiicourse) { if ($tiicourse->turnitin_cid == $tiicourseid and $tiicourse->courseid != $restore->course_id or $tiicourse->turnitin_cid != $tiicourseid and $tiicourse->courseid == $restore->course_id) { // If the Turnitin Class ID exists against a course already // and that course is not the course we are restoring to then do not restore $restorable = false; } else { if ($tiicourse->courseid == $restore->course_id) { $thiscourse = true; } } } // If the course class connection does not already exist OR if it does it is linked to this host course $insertcourse = new stdClass(); $insertcourse->courseid = $restore->course_id; // If the owner had been deleted before back up then // the username email address thing will have happened $owneremail = empty($course->owneremail) ? join(array_splice(explode(".", $course->ownerun), 0, -1)) : $course->owneremail; if (is_callable(array($DB, 'get_records'))) { $owner = $DB->get_record('user', array('email' => $owneremail)); } else { $owner = get_record('user', 'email', $owneremail); } if ($owner) { $insertcourse->ownerid = $owner->id; } else { // Turnitin class owner not found from email address etc create user account $newuser = false; $i = 0; while (!$newuser) { // Keep trying to create a new username $username = $i == 0 ? $course->ownerun : $course->ownerun . '_' . $i; // Append number if username exists $i++; $newuser = create_user_record($username, substr(rand(0, 9) . '_' . md5($course->ownerun), 0, 8)); $newuser->email = $owneremail; $newuser->firstname = $course->ownerfn; $newuser->lastname = $course->ownerln; if (is_callable(array($DB, 'update_record'))) { $DB->update_record("turnitintool_courses", $newuser); } else { update_record("turnitintool_courses", $newuser); } } $insertcourse->ownerid = $newuser->id; } $insertcourse->turnitin_ctl = $course->turnitin_ctl; $insertcourse->turnitin_cid = $course->turnitin_cid; if (is_callable(array($DB, 'insert_record')) and !$thiscourse) { $DB->insert_record("turnitintool_courses", $insertcourse); } else { if (!$thiscourse) { insert_record("turnitintool_courses", $insertcourse); } } if ($restore->course_startdateoffset) { restore_log_date_changes(get_string('modulename', 'turnitintool'), $restore, $info['MOD']['#'], array('TIMEDUE', 'TIMEAVAILABLE')); } $turnitintool->course = $restore->course_id; $turnitintool->name = backup_todb($info['MOD']['#']['NAME']['0']['#']); $turnitintool->grade = backup_todb($info['MOD']['#']['GRADE']['0']['#']); $turnitintool->numparts = backup_todb($info['MOD']['#']['NUMPARTS']['0']['#']); $turnitintool->defaultdtstart = backup_todb($info['MOD']['#']['DEFAULTDTSTART']['0']['#']); $turnitintool->defaultdtdue = backup_todb($info['MOD']['#']['DEFAULTDTDUE']['0']['#']); $turnitintool->defaultdtpost = backup_todb($info['MOD']['#']['DEFAULTDTPOST']['0']['#']); $turnitintool->anon = backup_todb($info['MOD']['#']['ANON']['0']['#']); $turnitintool->portfolio = backup_todb($info['MOD']['#']['PORTFOLIO']['0']['#']); $turnitintool->allowlate = backup_todb($info['MOD']['#']['ALLOWLATE']['0']['#']); $turnitintool->reportgenspeed = backup_todb($info['MOD']['#']['REPORTGENSPEED']['0']['#']); $turnitintool->submitpapersto = backup_todb($info['MOD']['#']['SUBMITPAPERSTO']['0']['#']); $turnitintool->spapercheck = backup_todb($info['MOD']['#']['SPAPERCHECK']['0']['#']); $turnitintool->internetcheck = backup_todb($info['MOD']['#']['INTERNETCHECK']['0']['#']); $turnitintool->journalcheck = backup_todb($info['MOD']['#']['JOURNALCHECK']['0']['#']); $turnitintool->maxfilesize = backup_todb($info['MOD']['#']['MAXFILESIZE']['0']['#']); $turnitintool->intro = backup_todb($info['MOD']['#']['INTRO']['0']['#']); $turnitintool->introformat = backup_todb($info['MOD']['#']['INTROFORMAT']['0']['#']); $turnitintool->timecreated = backup_todb($info['MOD']['#']['TIMECREATED']['0']['#']); $turnitintool->timemodified = backup_todb($info['MOD']['#']['TIMEMODIFIED']['0']['#']); $turnitintool->studentreports = backup_todb($info['MOD']['#']['STUDENTREPORTS']['0']['#']); $turnitintool->dateformat = backup_todb($info['MOD']['#']['DATEFORMAT']['0']['#']); $turnitintool->usegrademark = backup_todb($info['MOD']['#']['USEGRADEMARK']['0']['#']); $turnitintool->gradedisplay = backup_todb($info['MOD']['#']['GRADEDISPLAY']['0']['#']); $turnitintool->autoupdates = backup_todb($info['MOD']['#']['AUTOUPDATES']['0']['#']); $turnitintool->commentedittime = backup_todb($info['MOD']['#']['COMMENTEDITTIME']['0']['#']); $turnitintool->commentmaxsize = backup_todb($info['MOD']['#']['COMMENTMAXSIZE']['0']['#']); $turnitintool->autosubmission = backup_todb($info['MOD']['#']['AUTOSUBMISSION']['0']['#']); $turnitintool->shownonsubmission = backup_todb($info['MOD']['#']['SHOWNONSUBMISSION']['0']['#']); // Add exclude small matches data if present in backup file if (isset($info['MOD']['#']['EXCLUDEBIBLIO']['0']['#'])) { $turnitintool->excludebiblio = backup_todb($info['MOD']['#']['EXCLUDEBIBLIO']['0']['#']); $turnitintool->excludequoted = backup_todb($info['MOD']['#']['EXCLUDEQUOTED']['0']['#']); $turnitintool->excludevalue = backup_todb($info['MOD']['#']['EXCLUDEVALUE']['0']['#']); $turnitintool->excludetype = backup_todb($info['MOD']['#']['EXCLUDETYPE']['0']['#']); } // Add exclude small matches data if present in backup file if (isset($info['MOD']['#']['ERATER']['0']['#'])) { $turnitintool->erater = backup_todb($info['MOD']['#']['ERATER']['0']['#']); $turnitintool->erater_handbook = backup_todb($info['MOD']['#']['ERATERHANDBOOK']['0']['#']); $turnitintool->erater_dictionary = backup_todb($info['MOD']['#']['ERATERDICTIONARY']['0']['#']); $turnitintool->erater_spelling = backup_todb($info['MOD']['#']['ERATERSPELLING']['0']['#']); $turnitintool->erater_grammar = backup_todb($info['MOD']['#']['ERATERGRAMMAR']['0']['#']); $turnitintool->erater_usage = backup_todb($info['MOD']['#']['ERATERUSAGE']['0']['#']); $turnitintool->erater_mechanics = backup_todb($info['MOD']['#']['ERATERMECHANICS']['0']['#']); $turnitintool->erater_style = backup_todb($info['MOD']['#']['ERATERSTYLE']['0']['#']); } if (is_callable(array($DB, 'insert_record'))) { $newid = $DB->insert_record("turnitintool", $turnitintool); } else { $newid = insert_record("turnitintool", $turnitintool); } // Recreate the turnitintool_parts entries $newpartids = array(); foreach ($info['MOD']['#']['PARTS']['0']['#']['PART'] as $partarray) { $part = new stdClass(); $part->turnitintoolid = $newid; $part->partname = backup_todb($partarray['#']['PARTNAME']['0']['#']); $part->tiiassignid = backup_todb($partarray['#']['TIIASSIGNID']['0']['#']); $part->dtstart = backup_todb($partarray['#']['DTSTART']['0']['#']); $part->dtdue = backup_todb($partarray['#']['DTDUE']['0']['#']); $part->dtpost = backup_todb($partarray['#']['DTPOST']['0']['#']); $part->maxmarks = backup_todb($partarray['#']['MAXMARKS']['0']['#']); $part->deleted = backup_todb($partarray['#']['DELETED']['0']['#']); $oldpartid = backup_todb($partarray['#']['ID']['0']['#']); unset($part->id); if (is_callable(array($DB, 'insert_record'))) { $newpartid = $DB->insert_record("turnitintool_parts", $part); } else { $newpartid = insert_record("turnitintool_parts", $part); } $newpartids[$oldpartid] = $newpartid; } if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("modulename", "turnitintool") . " \"" . format_string(stripslashes($turnitintool->name), true) . "\"</li>"; } backup_flush(300); if ($newid) { backup_putid($restore->backup_unique_code, $mod->modtype, $mod->id, $newid); if (restore_userdata_selected($restore, 'turnitintool', $mod->id)) { $status = turnitintool_submissions_restore_mods($mod->id, $newid, $newpartids, $info, $restore) && $status; } } else { $status = false; } } else { $status = false; } return $status; }
/** * Copied from moodlelib:authenticate_user_login() * * WHY? because I need to hard code the plugins to auth_saml, and this user * may be set to any number of other types of login method * * First of all - make sure that they aren't nologin - we don't mess with that! * * * Given a username and password, this function looks them * up using the currently selected authentication mechanism, * and if the authentication is successful, it returns a * valid $user object from the 'user' table. * * Uses auth_ functions from the currently active auth module * * After authenticate_user_login() returns success, you will need to * log that the user has logged in, and call complete_user_login() to set * the session up. * * @uses $CFG * @param string $username User's username (with system magic quotes) * @param string $password User's password (with system magic quotes) * @return user|flase A {@link $USER} object or false if error */ function auth_onelogin_saml_authenticate_user_login($username, $password) { global $CFG, $DB; // ensure that only saml auth module is chosen $authsenabled = get_enabled_auth_plugins(); if ($user = get_complete_user_data('username', $username)) { # print_error(htmlspecialchars(print_r($user, true))); $auth = empty($user->auth) ? 'manual' : $user->auth; // use manual if auth not set if ($auth == 'nologin' or !is_enabled_auth($auth)) { add_to_log(0, 'login', 'error', 'index.php', $username); print_error('[client ' . getremoteaddr() . "] {$CFG->wwwroot} ---> DISABLED LOGIN: {$username} " . $_SERVER['HTTP_USER_AGENT']); return false; } } else { // check if there's a deleted record (cheaply) $query_conditions['username'] = $username; $query_conditions['deleted'] = 1; if ($DB->get_field('user', 'id', $query_conditions)) { print_error('[client ' . $_SERVER['REMOTE_ADDR'] . "] {$CFG->wwwroot} ---> DELETED LOGIN: {$username} " . $_SERVER['HTTP_USER_AGENT']); return false; } $auths = $authsenabled; $user = new object(); $user->id = 0; // User does not exist } // hard code SAML $auths = array('onelogin_saml'); foreach ($auths as $auth) { $authplugin = get_auth_plugin($auth); // on auth fail fall through to the next plugin if (!$authplugin->user_login($username, $password)) { continue; } // successful authentication if (!$user->id) { // if user not found, create him $user = create_user_record($username, $password, $auth); ## myDebugger("Attempted new user creation because user did not exist. Result is...<br /><br />".htmlspecialchars(print_r($user, true))); } if ($user->id) { // User already exists in database if (empty($user->auth)) { // For some reason auth isn't set yet $query_conditions['username'] = $username; $DB->set_field('user', 'auth', $auth, $query_conditions); $user->auth = $auth; } if (empty($user->firstaccess)) { //prevent firstaccess from remaining 0 for manual account that never required confirmation $query_conditions['id'] = $user->id; $DB->set_field('user', 'firstaccess', $user->timemodified, $query_conditions); $user->firstaccess = $user->timemodified; } if (empty($user->email) && stristr($username, "@")) { $query_conditions['id'] = $user->id; $DB->set_field('user', 'email', $username, $query_conditions); $user->email = $username; } if (empty($user->firstname)) { $query_conditions['id'] = $user->id; $DB->set_field('user', 'firstname', $username, $query_conditions); $user->firstname = $username; } // we don't want to upset the existing authentication schema for the user // update_internal_user_password($user, $password); // just in case salt or encoding were changed (magic quotes too one day) // update user record from external DB if (!$authplugin->is_internal()) { # myDebugger("Authplugin not internal: updating from external source..."); $user = update_user_record($username, get_auth_plugin($user->auth)); } } $authplugin->sync_roles($user); foreach ($authsenabled as $hau) { $hauth = get_auth_plugin($hau); $hauth->user_authenticated_hook($user, $username, $password); } if ($user->id === 0) { print_error("Failed to create user with the following details... <br /> <pre>" . htmlspecialchars(print_r($user, true)) . "</pre>"); return false; } return $user; } // failed if all the plugins have failed add_to_log(0, 'login', 'error', 'index.php', $username); //if (myDebugger('', DEBUG_ALL)) { print_error('[client ' . getremoteaddr() . "] {$CFG->wwwroot} ---> FAILED LOGIN: {$username} " . $_SERVER['HTTP_USER_AGENT']); //} return false; }
/** * Authentication hook - is called every time user hit the login page * The code is run only if the param code is mentionned. */ public function loginpage_hook() { global $USER, $SESSION, $CFG, $DB; // Check the Google authorization code. $authorizationcode = optional_param('code', '', PARAM_TEXT); if (!empty($authorizationcode)) { $authprovider = required_param('authprovider', PARAM_ALPHANUMEXT); require_once $CFG->dirroot . '/auth/googleoauth2/classes/provider/' . $authprovider . '.php'; $providerclassname = 'provideroauth2' . $authprovider; $provider = new $providerclassname(); // Try to get an access token (using the authorization code grant). $token = $provider->getAccessToken('authorization_code', ['code' => $authorizationcode]); $accesstoken = $token->accessToken; $refreshtoken = $token->refreshToken; $tokenexpires = $token->expires; // With access token request by curl the email address. if (!empty($accesstoken)) { try { // We got an access token, let's now get the user's details. $userdetails = $provider->getUserDetails($token); // Use these details to create a new profile. switch ($authprovider) { case 'battlenet': // Battlenet as no email notion. // TODO: need to check the idp table for matching user and request user to add his email. // TODO: It will be similar logic for twitter. $useremail = $userdetails->id . '@fakebattle.net'; break; case 'github': $useremails = $provider->getUserEmails($token); // Going to try to find someone with a similar email using googleoauth2 auth. $fallbackuseremail = ''; foreach ($useremails as $githubuseremail) { if ($githubuseremail->verified) { if ($DB->record_exists('user', array('auth' => 'googleoauth2', 'email' => $githubuseremail->email))) { $useremail = $githubuseremail->email; } $fallbackuseremail = $githubuseremail->email; } } // If we didn't find anyone then we take a verified email address. if (empty($useremail)) { $useremail = $fallbackuseremail; } break; case 'vk': // VK doesn't return the email address? if ($userdetails->uid) { $useremail = 'id' . $userdetails->uid . '@vkmessenger.com'; } break; default: $useremail = $userdetails->email; break; } $verified = 1; } catch (Exception $e) { // Failed to get user details. throw new moodle_exception('faileduserdetails', 'auth_googleoauth2'); } // Throw an error if the email address is not verified. if (!$verified) { throw new moodle_exception('emailaddressmustbeverified', 'auth_googleoauth2'); } // Prohibit login if email belongs to the prohibited domain. if ($err = email_is_not_allowed($useremail)) { throw new moodle_exception($err, 'auth_googleoauth2'); } // If email not existing in user database then create a new username (userX). if (empty($useremail) or $useremail != clean_param($useremail, PARAM_EMAIL)) { throw new moodle_exception('couldnotgetuseremail', 'auth_googleoauth2'); // TODO: display a link for people to retry. } // Get the user. // Don't bother with auth = googleoauth2 because authenticate_user_login() will fail it if it's not 'googleoauth2'. $user = $DB->get_record('user', array('email' => $useremail, 'deleted' => 0, 'mnethostid' => $CFG->mnet_localhost_id)); // Create the user if it doesn't exist. if (empty($user)) { // Deny login if setting "Prevent account creation when authenticating" is on. if ($CFG->authpreventaccountcreation) { throw new moodle_exception("noaccountyet", "auth_googleoauth2"); } // Get following incremented username. $googleuserprefix = core_text::strtolower(get_config('auth/googleoauth2', 'googleuserprefix')); $lastusernumber = get_config('auth/googleoauth2', 'lastusernumber'); $lastusernumber = empty($lastusernumber) ? 1 : $lastusernumber + 1; // Check the user doesn't exist. $nextuser = $DB->record_exists('user', array('username' => $googleuserprefix . $lastusernumber)); while ($nextuser) { $lastusernumber++; $nextuser = $DB->record_exists('user', array('username' => $googleuserprefix . $lastusernumber)); } set_config('lastusernumber', $lastusernumber, 'auth/googleoauth2'); $username = $googleuserprefix . $lastusernumber; // Retrieve more information from the provider. $newuser = new stdClass(); $newuser->email = $useremail; switch ($authprovider) { case 'battlenet': // Battlenet as no firstname/lastname notion. $newuser->firstname = $userdetails->display_name; $newuser->lastname = '[' . $userdetails->clan_tag . ']'; break; case 'github': case 'dropbox': // As Github/Dropbox doesn't provide firstname/lastname, we'll split the name at the first whitespace. $githubusername = explode(' ', $userdetails->name, 2); $newuser->firstname = $githubusername[0]; $newuser->lastname = $githubusername[1]; break; default: $newuser->firstname = $userdetails->firstName; $newuser->lastname = $userdetails->lastName; break; } // Some providers allow empty firstname and lastname. if (empty($newuser->firstname)) { $newuser->firstname = get_string('unknownfirstname', 'auth_googleoauth2'); } if (empty($newuser->lastname)) { $newuser->lastname = get_string('unknownlastname', 'auth_googleoauth2'); } // Retrieve country and city if the provider failed to give it. if (!isset($newuser->country) or !isset($newuser->city)) { $googleipinfodbkey = get_config('auth/googleoauth2', 'googleipinfodbkey'); if (!empty($googleipinfodbkey)) { require_once $CFG->libdir . '/filelib.php'; $curl = new curl(); $locationdata = $curl->get('http://api.ipinfodb.com/v3/ip-city/?key=' . $googleipinfodbkey . '&ip=' . getremoteaddr() . '&format=json'); $locationdata = json_decode($locationdata); } if (!empty($locationdata)) { // TODO: check that countryCode does match the Moodle country code. $newuser->country = isset($newuser->country) ? isset($newuser->country) : $locationdata->countryCode; $newuser->city = isset($newuser->city) ? isset($newuser->city) : $locationdata->cityName; } } create_user_record($username, '', 'googleoauth2'); } else { $username = $user->username; } // Authenticate the user. // TODO: delete this log later. require_once $CFG->dirroot . '/auth/googleoauth2/lib.php'; $userid = empty($user) ? 'new user' : $user->id; oauth_add_to_log(SITEID, 'auth_googleoauth2', '', '', $username . '/' . $useremail . '/' . $userid); $user = authenticate_user_login($username, null); if ($user) { // Set a cookie to remember what auth provider was selected. setcookie('MOODLEGOOGLEOAUTH2_' . $CFG->sessioncookie, $authprovider, time() + DAYSECS * 60, $CFG->sessioncookiepath, $CFG->sessioncookiedomain, $CFG->cookiesecure, $CFG->cookiehttponly); // Prefill more user information if new user. if (!empty($newuser)) { $newuser->id = $user->id; $DB->update_record('user', $newuser); $user = (object) array_merge((array) $user, (array) $newuser); } complete_user_login($user); // Let's save/update the access token for this user. $cansaveaccesstoken = get_config('auth/googleoauth2', 'saveaccesstoken'); if (!empty($cansaveaccesstoken)) { $existingaccesstoken = $DB->get_record('auth_googleoauth2_user_idps', array('userid' => $user->id, 'provider' => $authprovider)); if (empty($existingaccesstoken)) { $accesstokenrow = new stdClass(); $accesstokenrow->userid = $user->id; switch ($authprovider) { case 'battlenet': $accesstokenrow->provideruserid = $userdetails->id; break; default: $accesstokenrow->provideruserid = $userdetails->uid; break; } $accesstokenrow->provider = $authprovider; $accesstokenrow->accesstoken = $accesstoken; $accesstokenrow->refreshtoken = $refreshtoken; $accesstokenrow->expires = $tokenexpires; $DB->insert_record('auth_googleoauth2_user_idps', $accesstokenrow); } else { $existingaccesstoken->accesstoken = $accesstoken; $DB->update_record('auth_googleoauth2_user_idps', $existingaccesstoken); } } // Check if the user picture is the default and retrieve the provider picture. if (empty($user->picture)) { switch ($authprovider) { case 'battlenet': require_once $CFG->libdir . '/filelib.php'; require_once $CFG->libdir . '/gdlib.php'; $imagefilename = $CFG->tempdir . '/googleoauth2-portrait-' . $user->id; $imagecontents = download_file_content($userdetails->portrait_url); file_put_contents($imagefilename, $imagecontents); if ($newrev = process_new_icon(context_user::instance($user->id), 'user', 'icon', 0, $imagefilename)) { $DB->set_field('user', 'picture', $newrev, array('id' => $user->id)); } unlink($imagefilename); break; default: // TODO retrieve other provider profile pictures. break; } } // Create event for authenticated user. $event = \auth_googleoauth2\event\user_loggedin::create(array('context' => context_system::instance(), 'objectid' => $user->id, 'relateduserid' => $user->id, 'other' => array('accesstoken' => $accesstoken))); $event->trigger(); // Redirection. if (user_not_fully_set_up($USER)) { $urltogo = $CFG->wwwroot . '/user/edit.php'; // We don't delete $SESSION->wantsurl yet, so we get there later. } else { if (isset($SESSION->wantsurl) and strpos($SESSION->wantsurl, $CFG->wwwroot) === 0) { $urltogo = $SESSION->wantsurl; // Because it's an address in this site. unset($SESSION->wantsurl); } else { // No wantsurl stored or external - go to homepage. $urltogo = $CFG->wwwroot . '/'; unset($SESSION->wantsurl); } } $loginrecord = array('userid' => $USER->id, 'time' => time(), 'auth' => 'googleoauth2', 'subtype' => $authprovider); $DB->insert_record('auth_googleoauth2_logins', $loginrecord); redirect($urltogo); } else { // Authenticate_user_login() failure, probably email registered by another auth plugin. // Do a check to confirm this hypothesis. $userexist = $DB->get_record('user', array('email' => $useremail)); if (!empty($userexist) and $userexist->auth != 'googleoauth2') { $a = new stdClass(); $a->loginpage = (string) new moodle_url(empty($CFG->alternateloginurl) ? '/login/index.php' : $CFG->alternateloginurl); $a->forgotpass = (string) new moodle_url('/login/forgot_password.php'); throw new moodle_exception('couldnotauthenticateuserlogin', 'auth_googleoauth2', '', $a); } else { throw new moodle_exception('couldnotauthenticate', 'auth_googleoauth2'); } } } else { throw new moodle_exception('couldnotgetgoogleaccesstoken', 'auth_googleoauth2'); } } else { // If you are having issue with the display buttons option, add the button code directly in the theme login page. if (get_config('auth/googleoauth2', 'oauth2displaybuttons') and empty($_POST['username']) and empty($_POST['password'])) { // Display the button on the login page. require_once $CFG->dirroot . '/auth/googleoauth2/lib.php'; // Insert the html code below the login field. // Code/Solution from Elcentra plugin: https://moodle.org/plugins/view/auth_elcentra. global $PAGE, $CFG; $PAGE->requires->jquery(); $content = str_replace(array("\n", "\r"), array("\\\n", "\\\r"), auth_googleoauth2_display_buttons(false)); $PAGE->requires->css('/auth/googleoauth2/style.css'); $PAGE->requires->js_init_code("buttonsCodeOauth2 = '{$content}';"); $PAGE->requires->js(new moodle_url($CFG->wwwroot . "/auth/googleoauth2/script.js")); } } }
/** * Open user account using SREG & AX data if available * If no matching user found and create flag is true, creates new user account * * @access private * @param object &$resp An OpenID consumer response object * @param boolean $create_flag - set if account creation permitted, default: true * @uses $CFG * @uses $USER * @uses $openid_tmp_login * @return object The new user */ function _open_account(&$resp, $create_flag = true) { global $CFG, $USER, $openid_tmp_login; $url = $resp->identity_url; $password = hash_internal_user_password('openid'); $server = $resp->endpoint->server_url; $user = openid_resp_to_user($resp); if ($user == false) { // multiple matches to users! Don't know which user to pick. print_error('auth_openid_multiple_matches', 'auth_openid'); return false; // won't get here. } if (isset($user->id)) { $openid_tmp_login = true; $openid_action = 'change'; if ($user->auth == 'openid') { if (empty($this->config->auth_openid_allow_muliple)) { print_error('auth_openid_no_multiple', 'auth_openid'); return false; } $openid_action = 'append'; } else { if (empty($this->config->auth_openid_confirm_switch)) { openid_if_unique_change_account($user, $url); return $USER; } } $USER = clone $user; // To clone or not to clone //$mode = optional_param('openid_mode', null); //error_log("auth/openid/auth.php::_open_account() setting openid_mode={$mode} (openid_process_url={$openid_process_url})"); redirect("{$CFG->wwwroot}/auth/openid/actions.php?openid_tmp_login=1&openid_action={$openid_action}&openid_url={$url}"); // Try to get it not to make second request to be accepted, double confirm - TBD: openid_mode=??? } if (!$create_flag) { // Error: This site is configured to disallow new users via OpenID print_error('auth_openid_require_account', 'auth_openid'); return false; // won't get here. } $usertmp = create_user_record($user->username, $password, 'openid'); $user->id = $usertmp->id; openid_append_url($user, $url); if (!isset($user->city) || $user->city == '') { //use "*" as the default city name $user->city = '*'; } if (empty($user->country) && !empty($CFG->country)) { //use the configured default country code $user->country = $CFG->country; } if (empty($user->country)) { //out of other options, to try to copy the admin's country if ($admin = get_admin()) { $user->country = $admin->country; } } update_record('user', $user); $user = get_complete_user_data('id', $user->id); events_trigger('user_created', $user); // BJB120125 - moved from below redirect for alfresco, etc... if (function_exists('on_openid_create_account')) { on_openid_create_account($resp, $user); } // Redirect the user to their profile page if not set up properly if (!empty($user) && user_not_fully_set_up($user)) { $USER = clone $user; $urltogo = $CFG->wwwroot . '/user/edit.php'; redirect($urltogo); } if (openid_server_requires_confirm($server, $this->config)) { $secret = random_string(15); set_field('user', 'secret', $secret, 'id', $user->id); $user->secret = $secret; set_field('user', 'confirmed', 0, 'id', $user->id); $user->confirmed = 0; openid_send_confirmation_email($user); } return $user; }
/** * Authenticates a user against the chosen authentication mechanism * * Given a username and password, this function looks them * up using the currently selected authentication mechanism, * and if the authentication is successful, it returns a * valid $user object from the 'user' table. * * Uses auth_ functions from the currently active auth module * * After authenticate_user_login() returns success, you will need to * log that the user has logged in, and call complete_user_login() to set * the session up. * * Note: this function works only with non-mnet accounts! * * @param string $username User's username * @param string $password User's password * @param bool $ignorelockout useful when guessing is prevented by other mechanism such as captcha or SSO * @param int $failurereason login failure reason, can be used in renderers (it may disclose if account exists) * @return stdClass|false A {@link $USER} object or false if error */ function authenticate_user_login($username, $password, $ignorelockout = false, &$failurereason = null) { global $CFG, $DB; require_once "{$CFG->libdir}/authlib.php"; $authsenabled = get_enabled_auth_plugins(); if ($user = get_complete_user_data('username', $username, $CFG->mnet_localhost_id)) { // Use manual if auth not set. $auth = empty($user->auth) ? 'manual' : $user->auth; if (!empty($user->suspended)) { add_to_log(SITEID, 'login', 'error', 'index.php', $username); error_log('[client ' . getremoteaddr() . "] {$CFG->wwwroot} Suspended Login: {$username} " . $_SERVER['HTTP_USER_AGENT']); $failurereason = AUTH_LOGIN_SUSPENDED; return false; } if ($auth == 'nologin' or !is_enabled_auth($auth)) { add_to_log(SITEID, 'login', 'error', 'index.php', $username); error_log('[client ' . getremoteaddr() . "] {$CFG->wwwroot} Disabled Login: {$username} " . $_SERVER['HTTP_USER_AGENT']); // Legacy way to suspend user. $failurereason = AUTH_LOGIN_SUSPENDED; return false; } $auths = array($auth); } else { // Check if there's a deleted record (cheaply), this should not happen because we mangle usernames in delete_user(). if ($DB->get_field('user', 'id', array('username' => $username, 'mnethostid' => $CFG->mnet_localhost_id, 'deleted' => 1))) { error_log('[client ' . getremoteaddr() . "] {$CFG->wwwroot} Deleted Login: {$username} " . $_SERVER['HTTP_USER_AGENT']); $failurereason = AUTH_LOGIN_NOUSER; return false; } // Do not try to authenticate non-existent accounts when user creation is not disabled. if (!empty($CFG->authpreventaccountcreation)) { add_to_log(SITEID, 'login', 'error', 'index.php', $username); error_log('[client ' . getremoteaddr() . "] {$CFG->wwwroot} Unknown user, can not create new accounts: {$username} " . $_SERVER['HTTP_USER_AGENT']); $failurereason = AUTH_LOGIN_NOUSER; return false; } // User does not exist. $auths = $authsenabled; $user = new stdClass(); $user->id = 0; } if ($ignorelockout) { // Some other mechanism protects against brute force password guessing, for example login form might include reCAPTCHA // or this function is called from a SSO script. } else { if ($user->id) { // Verify login lockout after other ways that may prevent user login. if (login_is_lockedout($user)) { add_to_log(SITEID, 'login', 'error', 'index.php', $username); error_log('[client ' . getremoteaddr() . "] {$CFG->wwwroot} Login lockout: {$username} " . $_SERVER['HTTP_USER_AGENT']); $failurereason = AUTH_LOGIN_LOCKOUT; return false; } } else { // We can not lockout non-existing accounts. } } foreach ($auths as $auth) { $authplugin = get_auth_plugin($auth); // On auth fail fall through to the next plugin. if (!$authplugin->user_login($username, $password)) { continue; } // Successful authentication. if ($user->id) { // User already exists in database. if (empty($user->auth)) { // For some reason auth isn't set yet. $DB->set_field('user', 'auth', $auth, array('username' => $username)); $user->auth = $auth; } // If the existing hash is using an out-of-date algorithm (or the legacy md5 algorithm), then we should update to // the current hash algorithm while we have access to the user's password. update_internal_user_password($user, $password); if ($authplugin->is_synchronised_with_external()) { // Update user record from external DB. $user = update_user_record($username); } } else { // Create account, we verified above that user creation is allowed. $user = create_user_record($username, $password, $auth); } $authplugin->sync_roles($user); foreach ($authsenabled as $hau) { $hauth = get_auth_plugin($hau); $hauth->user_authenticated_hook($user, $username, $password); } if (empty($user->id)) { $failurereason = AUTH_LOGIN_NOUSER; return false; } if (!empty($user->suspended)) { // Just in case some auth plugin suspended account. add_to_log(SITEID, 'login', 'error', 'index.php', $username); error_log('[client ' . getremoteaddr() . "] {$CFG->wwwroot} Suspended Login: {$username} " . $_SERVER['HTTP_USER_AGENT']); $failurereason = AUTH_LOGIN_SUSPENDED; return false; } login_attempt_valid($user); $failurereason = AUTH_LOGIN_OK; return $user; } // Failed if all the plugins have failed. add_to_log(SITEID, 'login', 'error', 'index.php', $username); if (debugging('', DEBUG_ALL)) { error_log('[client ' . getremoteaddr() . "] {$CFG->wwwroot} Failed Login: {$username} " . $_SERVER['HTTP_USER_AGENT']); } if ($user->id) { login_attempt_failed($user); $failurereason = AUTH_LOGIN_FAILED; } else { $failurereason = AUTH_LOGIN_NOUSER; } return false; }
/** * Creates a new Joomdle user * XXX Also used to update user profile if the user already exists * * @param string $username Joomla username */ function create_joomdle_user($username, $app = '') { global $CFG, $DB; $username = utf8_decode($username); $username = strtolower($username); /* Creamos el nuevo usuario de Moodle si no está creado */ $conditions = array('username' => $username); $user = $DB->get_record('user', $conditions); if (!$user) { $user = create_user_record($username, "", "joomdle"); } /* Obtenemos la información del usuario en Joomla */ $juser_info = $this->call_method("getUserInfo", $username, $app); if (array_key_exists('email', $juser_info)) { $email = $juser_info['email']; } else { $email = ''; } if (array_key_exists('firstname', $juser_info)) { $firstname = $juser_info['firstname']; } else { $firstname = ''; } if (array_key_exists('lastname', $juser_info)) { $lastname = $juser_info['lastname']; } else { $lastname = ''; } if (array_key_exists('city', $juser_info)) { $city = $juser_info['city']; } else { $city = ''; } if (array_key_exists('country', $juser_info)) { $country = $juser_info['country']; } else { $country = ''; } if (array_key_exists('lang', $juser_info)) { $lang = $juser_info['lang']; } else { $lang = ''; } if (array_key_exists('timezone', $juser_info)) { $timezone = $juser_info['timezone']; } else { $timezone = ''; } if (array_key_exists('phone1', $juser_info)) { $phone1 = $juser_info['phone1']; } else { $phone1 = ''; } if (array_key_exists('phone2', $juser_info)) { $phone2 = $juser_info['phone2']; } else { $phone2 = ''; } if (array_key_exists('address', $juser_info)) { $address = $juser_info['address']; } else { $address = ''; } if (array_key_exists('description', $juser_info)) { $description = $juser_info['description']; } else { $description = ''; } if (array_key_exists('institution', $juser_info)) { $institution = $juser_info['institution']; } else { $institution = ''; } if (array_key_exists('url', $juser_info)) { $url = $juser_info['url']; } else { $url = ''; } if (array_key_exists('icq', $juser_info)) { $icq = $juser_info['icq']; } else { $icq = ''; } if (array_key_exists('skype', $juser_info)) { $skype = $juser_info['skype']; } else { $skype = ''; } if (array_key_exists('aim', $juser_info)) { $aim = $juser_info['aim']; } else { $aim = ''; } if (array_key_exists('yahoo', $juser_info)) { $yahoo = $juser_info['yahoo']; } else { $yahoo = ''; } if (array_key_exists('msn', $juser_info)) { $msn = $juser_info['msn']; } else { $msn = ''; } if (array_key_exists('idnumber', $juser_info)) { $idnumber = $juser_info['idnumber']; } else { $idnumber = ''; } if (array_key_exists('department', $juser_info)) { $department = $juser_info['department']; } else { $department = ''; } //XXX Maybe this can be optimized for a single DB call...$bool = update_record('user', addslashes_recursive($localuser)); en ment/aut.php if (!xmlrpc_is_fault($juser_info)) { /* Actualizamos la informacion del usuario recien creado con los datos de Joomla */ $conditions = array('id' => $user->id); if ($firstname) { $DB->set_field('user', 'firstname', $firstname, $conditions); } if ($lastname) { $DB->set_field('user', 'lastname', $lastname, $conditions); } if ($email) { $DB->set_field('user', 'email', $email, $conditions); } /* Set first access as now */ $DB->set_field('user', 'firstaccess', time(), $conditions); /* Optional data in Joomla, only fill if has a value */ if ($city) { $DB->set_field('user', 'city', $city, $conditions); } if ($country) { $DB->set_field('user', 'country', substr($country, 0, 2), $conditions); } // $DB->set_field('user', 'country', $country, $conditions); if ($lang) { $DB->set_field('user', 'lang', $lang, $conditions); } if ($timezone) { $DB->set_field('user', 'timezone', $timezone, $conditions); } if ($phone1) { $DB->set_field('user', 'phone1', $phone1, $conditions); } if ($phone2) { $DB->set_field('user', 'phone2', $phone2, $conditions); } if ($address) { $DB->set_field('user', 'address', $address, $conditions); } if ($description) { $DB->set_field('user', 'description', $description, $conditions); } if ($institution) { $DB->set_field('user', 'institution', $institution, $conditions); } if ($url) { $DB->set_field('user', 'url', $url, $conditions); } if ($icq) { $DB->set_field('user', 'icq', $icq, $conditions); } if ($skype) { $DB->set_field('user', 'skype', $skype, $conditions); } if ($aim) { $DB->set_field('user', 'aim', $aim, $conditions); } if ($yahoo) { $DB->set_field('user', 'yahoo', $yahoo, $conditions); } if ($msn) { $DB->set_field('user', 'msn', $msn, $conditions); } if ($idnumber) { $DB->set_field('user', 'idnumber', $idnumber, $conditions); } if ($department) { $DB->set_field('user', 'department', $department, $conditions); } } /* Get user pic */ if (array_key_exists('pic_url', $juser_info) && $juser_info['pic_url']) { if ($juser_info['pic_url'] != 'none') { $joomla_url = get_config(NULL, 'joomla_url'); $pic_url = $joomla_url . '/' . $juser_info['pic_url']; //$pic = @file_get_contents ($pic_url, false, NULL); $pic = $this->get_file($pic_url); if ($pic) { //$pic = file_get_contents ($pic_url, false, NULL); $pic = $this->get_file_curl($pic_url); $tmp_file = $CFG->dataroot . '/temp/' . 'tmp_pic'; file_put_contents($tmp_file, $pic); $context = get_context_instance(CONTEXT_USER, $user->id); process_new_icon($context, 'user', 'icon', 0, $tmp_file); $conditions = array('id' => $user->id); $DB->set_field('user', 'picture', 1, $conditions); } } } /* Custom fields */ if ($fields = $DB->get_records('user_info_field')) { foreach ($fields as $field) { if (array_key_exists('cf_' . $field->id, $juser_info) && $juser_info['cf_' . $field->id]) { $data = new stdClass(); $data->fieldid = $field->id; $data->data = $juser_info['cf_' . $field->id]; $data->userid = $user->id; /* update custom field */ if ($dataid = $DB->get_field('user_info_data', 'id', array('userid' => $user->id, 'fieldid' => $data->fieldid))) { $data->id = $dataid; $DB->update_record('user_info_data', $data); } else { $DB->insert_record('user_info_data', $data); } } } } return 1; }
/** * Given a username and password, this function looks them * up using the currently selected authentication mechanism, * and if the authentication is successful, it returns a * valid $user object from the 'user' table. * * Uses auth_ functions from the currently active auth module * * After authenticate_user_login() returns success, you will need to * log that the user has logged in, and call complete_user_login() to set * the session up. * * @uses $CFG * @param string $username User's username (with system magic quotes) * @param string $password User's password (with system magic quotes) * @return user|flase A {@link $USER} object or false if error */ function authenticate_user_login($username, $password) { global $CFG; $authsenabled = get_enabled_auth_plugins(); if ($user = get_complete_user_data('username', $username)) { $auth = empty($user->auth) ? 'manual' : $user->auth; // use manual if auth not set if ($auth == 'nologin' or !is_enabled_auth($auth)) { add_to_log(0, 'login', 'error', 'index.php', $username); error_log('[client ' . getremoteaddr() . "] {$CFG->wwwroot} Disabled Login: {$username} " . $_SERVER['HTTP_USER_AGENT']); return false; } $auths = array($auth); } else { // check if there's a deleted record (cheaply) if (get_field('user', 'id', 'username', $username, 'deleted', 1, '')) { error_log('[client ' . $_SERVER['REMOTE_ADDR'] . "] {$CFG->wwwroot} Deleted Login: {$username} " . $_SERVER['HTTP_USER_AGENT']); return false; } $auths = $authsenabled; $user = new object(); $user->id = 0; // User does not exist } foreach ($auths as $auth) { $authplugin = get_auth_plugin($auth); // on auth fail fall through to the next plugin if (!$authplugin->user_login($username, $password)) { continue; } // successful authentication if ($user->id) { // User already exists in database if (empty($user->auth)) { // For some reason auth isn't set yet set_field('user', 'auth', $auth, 'username', $username); $user->auth = $auth; } if (empty($user->firstaccess)) { //prevent firstaccess from remaining 0 for manual account that never required confirmation set_field('user', 'firstaccess', $user->timemodified, 'id', $user->id); $user->firstaccess = $user->timemodified; } update_internal_user_password($user, $password); // just in case salt or encoding were changed (magic quotes too one day) if (!$authplugin->is_internal()) { // update user record from external DB $user = update_user_record($username, get_auth_plugin($user->auth)); } } else { // if user not found, create him $user = create_user_record($username, $password, $auth); } $authplugin->sync_roles($user); foreach ($authsenabled as $hau) { $hauth = get_auth_plugin($hau); $hauth->user_authenticated_hook($user, $username, $password); } /// Log in to a second system if necessary /// NOTICE: /sso/ will be moved to auth and deprecated soon; use user_authenticated_hook() instead if (!empty($CFG->sso)) { include_once $CFG->dirroot . '/sso/' . $CFG->sso . '/lib.php'; if (function_exists('sso_user_login')) { if (!sso_user_login($username, $password)) { // Perform the signon process notify('Second sign-on failed'); } } } if ($user->id === 0) { return false; } return $user; } // failed if all the plugins have failed add_to_log(0, 'login', 'error', 'index.php', $username); if (debugging('', DEBUG_ALL)) { error_log('[client ' . getremoteaddr() . "] {$CFG->wwwroot} Failed Login: {$username} " . $_SERVER['HTTP_USER_AGENT']); } return false; }
<?php // very quick & dirty hack to get a database full of users require_once dirname(dirname(dirname(__FILE__))) . '/config.php'; require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM)); $strole = get_field('role', 'id', 'shortname', 'seniorteacher'); $mtrole = get_field('role', 'id', 'shortname', 'masterteacher'); $ptrole = get_field('role', 'id', 'shortname', 'participatingteacher'); $users = array('st' => array('firstname' => 'Senior', 'lastname' => 'Teacher 1', 'email' => '*****@*****.**', 'roleid' => $strole), 'mt' => array('firstname' => 'Master', 'lastname' => 'Teacher 1', 'email' => '*****@*****.**', 'roleid' => $mtrole), 'pt1' => array('firstname' => 'Participating 1', 'lastname' => 'Teacher 1', 'email' => '*****@*****.**', 'roleid' => $ptrole), 'pt2' => array('firstname' => 'Participating 2', 'lastname' => 'Teacher 2', 'email' => '*****@*****.**', 'roleid' => $ptrole), 'pt3' => array('firstname' => 'Participating 3', 'lastname' => 'Teacher 3', 'email' => '*****@*****.**', 'roleid' => $ptrole)); $sitecontext = get_context_instance(CONTEXT_COURSE, SITEID); foreach ($users as $user) { $user = (object) $user; $u = create_user_record(str_replace(' ', '', strtolower($user->firstname)), 'moodle'); $user->id = $u->id; update_record('user', $user); role_assign($user->roleid, $user->id, 0, $sitecontext->id); } echo 'done';
public function test_plugin() { global $DB, $CFG; $this->resetAfterTest(false); // NOTE: It is strongly discouraged to create new tables in advanced_testcase classes, // but there is no other simple way to test ext database enrol sync, so let's // disable transactions are try to cleanup after the tests. $this->preventResetByRollback(); $this->init_auth_database(); /** @var auth_plugin_db $auth */ $auth = get_auth_plugin('db'); $authdb = $auth->db_init(); // Test adodb may access the table. $user1 = (object) array('name' => 'u1', 'pass' => 'heslo', 'email' => '*****@*****.**'); $user1->id = $DB->insert_record('auth_db_users', $user1); $sql = "SELECT * FROM {$auth->config->table}"; $rs = $authdb->Execute($sql); $this->assertInstanceOf('ADORecordSet', $rs); $this->assertFalse($rs->EOF); $fields = $rs->FetchRow(); $this->assertTrue(is_array($fields)); $this->assertTrue($rs->EOF); $rs->Close(); $authdb->Close(); // Test bulk user account creation. $user2 = (object) array('name' => 'u2', 'pass' => 'heslo', 'email' => '*****@*****.**'); $user2->id = $DB->insert_record('auth_db_users', $user2); $user3 = (object) array('name' => 'admin', 'pass' => 'heslo', 'email' => '*****@*****.**'); // Should be skipped. $user3->id = $DB->insert_record('auth_db_users', $user3); $this->assertCount(2, $DB->get_records('user')); $trace = new null_progress_trace(); $auth->sync_users($trace, false); $this->assertEquals(4, $DB->count_records('user')); $u1 = $DB->get_record('user', array('username' => $user1->name, 'auth' => 'db')); $this->assertSame($user1->email, $u1->email); $u2 = $DB->get_record('user', array('username' => $user2->name, 'auth' => 'db')); $this->assertSame($user2->email, $u2->email); $admin = $DB->get_record('user', array('username' => 'admin', 'auth' => 'manual')); $this->assertNotEmpty($admin); // Test sync updates. $user2b = clone $user2; $user2b->email = '*****@*****.**'; $DB->update_record('auth_db_users', $user2b); $auth->sync_users($trace, false); $this->assertEquals(4, $DB->count_records('user')); $u2 = $DB->get_record('user', array('username' => $user2->name)); $this->assertSame($user2->email, $u2->email); $auth->sync_users($trace, true); $this->assertEquals(4, $DB->count_records('user')); $u2 = $DB->get_record('user', array('username' => $user2->name)); $this->assertSame($user2->email, $u2->email); set_config('field_updatelocal_email', 'onlogin', 'auth/db'); $auth->config->field_updatelocal_email = 'onlogin'; $auth->sync_users($trace, false); $this->assertEquals(4, $DB->count_records('user')); $u2 = $DB->get_record('user', array('username' => $user2->name)); $this->assertSame($user2->email, $u2->email); $auth->sync_users($trace, true); $this->assertEquals(4, $DB->count_records('user')); $u2 = $DB->get_record('user', array('username' => $user2->name)); $this->assertSame($user2b->email, $u2->email); // Test sync deletes and suspends. $DB->delete_records('auth_db_users', array('id' => $user2->id)); $this->assertCount(2, $DB->get_records('auth_db_users')); unset($user2); unset($user2b); $auth->sync_users($trace, false); $this->assertEquals(4, $DB->count_records('user')); $this->assertEquals(0, $DB->count_records('user', array('deleted' => 1))); $this->assertEquals(0, $DB->count_records('user', array('suspended' => 1))); set_config('removeuser', AUTH_REMOVEUSER_SUSPEND, 'auth/db'); $auth->config->removeuser = AUTH_REMOVEUSER_SUSPEND; $auth->sync_users($trace, false); $this->assertEquals(4, $DB->count_records('user')); $this->assertEquals(0, $DB->count_records('user', array('deleted' => 1))); $this->assertEquals(1, $DB->count_records('user', array('suspended' => 1))); $user2 = (object) array('name' => 'u2', 'pass' => 'heslo', 'email' => '*****@*****.**'); $user2->id = $DB->insert_record('auth_db_users', $user2); $auth->sync_users($trace, false); $this->assertEquals(4, $DB->count_records('user')); $this->assertEquals(0, $DB->count_records('user', array('deleted' => 1))); $this->assertEquals(0, $DB->count_records('user', array('suspended' => 1))); $DB->delete_records('auth_db_users', array('id' => $user2->id)); set_config('removeuser', AUTH_REMOVEUSER_FULLDELETE, 'auth/db'); $auth->config->removeuser = AUTH_REMOVEUSER_FULLDELETE; $auth->sync_users($trace, false); $this->assertEquals(4, $DB->count_records('user')); $this->assertEquals(1, $DB->count_records('user', array('deleted' => 1))); $this->assertEquals(0, $DB->count_records('user', array('suspended' => 1))); $user2 = (object) array('name' => 'u2', 'pass' => 'heslo', 'email' => '*****@*****.**'); $user2->id = $DB->insert_record('auth_db_users', $user2); $auth->sync_users($trace, false); $this->assertEquals(5, $DB->count_records('user')); $this->assertEquals(1, $DB->count_records('user', array('deleted' => 1))); $this->assertEquals(0, $DB->count_records('user', array('suspended' => 1))); // Test user_login(). $user3 = (object) array('name' => 'u3', 'pass' => 'heslo', 'email' => '*****@*****.**'); $user3->id = $DB->insert_record('auth_db_users', $user3); $this->assertFalse($auth->user_login('u4', 'heslo')); $this->assertTrue($auth->user_login('u1', 'heslo')); $this->assertFalse($DB->record_exists('user', array('username' => 'u3', 'auth' => 'db'))); $this->assertTrue($auth->user_login('u3', 'heslo')); $this->assertFalse($DB->record_exists('user', array('username' => 'u3', 'auth' => 'db'))); set_config('passtype', 'md5', 'auth/db'); $auth->config->passtype = 'md5'; $user3->pass = md5('heslo'); $DB->update_record('auth_db_users', $user3); $this->assertTrue($auth->user_login('u3', 'heslo')); set_config('passtype', 'sh1', 'auth/db'); $auth->config->passtype = 'sha1'; $user3->pass = sha1('heslo'); $DB->update_record('auth_db_users', $user3); $this->assertTrue($auth->user_login('u3', 'heslo')); set_config('passtype', 'internal', 'auth/db'); $auth->config->passtype = 'internal'; create_user_record('u3', 'heslo', 'db'); $this->assertTrue($auth->user_login('u3', 'heslo')); $DB->delete_records('auth_db_users', array('id' => $user3->id)); set_config('removeuser', AUTH_REMOVEUSER_KEEP, 'auth/db'); $auth->config->removeuser = AUTH_REMOVEUSER_KEEP; $this->assertTrue($auth->user_login('u3', 'heslo')); set_config('removeuser', AUTH_REMOVEUSER_SUSPEND, 'auth/db'); $auth->config->removeuser = AUTH_REMOVEUSER_SUSPEND; $this->assertFalse($auth->user_login('u3', 'heslo')); set_config('removeuser', AUTH_REMOVEUSER_FULLDELETE, 'auth/db'); $auth->config->removeuser = AUTH_REMOVEUSER_FULLDELETE; $this->assertFalse($auth->user_login('u3', 'heslo')); set_config('passtype', 'sh1', 'auth/db'); $auth->config->passtype = 'sha1'; $this->assertFalse($auth->user_login('u3', 'heslo')); // Test login create and update. $user4 = (object) array('name' => 'u4', 'pass' => 'heslo', 'email' => '*****@*****.**'); $user4->id = $DB->insert_record('auth_db_users', $user4); set_config('passtype', 'plaintext', 'auth/db'); $auth->config->passtype = 'plaintext'; $iuser4 = create_user_record('u4', 'heslo', 'db'); $this->assertNotEmpty($iuser4); $this->assertSame($user4->name, $iuser4->username); $this->assertSame($user4->email, $iuser4->email); $this->assertSame('db', $iuser4->auth); $this->assertSame($CFG->mnet_localhost_id, $iuser4->mnethostid); $user4b = clone $user4; $user4b->email = '*****@*****.**'; $DB->update_record('auth_db_users', $user4b); set_config('field_updatelocal_email', 'oncreate', 'auth/db'); $auth->config->field_updatelocal_email = 'oncreate'; update_user_record('u4'); $iuser4 = $DB->get_record('user', array('id' => $iuser4->id)); $this->assertSame($user4->email, $iuser4->email); set_config('field_updatelocal_email', 'onlogin', 'auth/db'); $auth->config->field_updatelocal_email = 'onlogin'; update_user_record('u4'); $iuser4 = $DB->get_record('user', array('id' => $iuser4->id)); $this->assertSame($user4b->email, $iuser4->email); // Test user_exists() $this->assertTrue($auth->user_exists('u1')); $this->assertTrue($auth->user_exists('admin')); $this->assertFalse($auth->user_exists('u3')); $this->assertTrue($auth->user_exists('u4')); $this->cleanup_auth_database(); }
/** * Validate that counting the number of role assignments on a particular * cluster for a particular role respects special userset permissions */ public function test_clusterrolepagecountroleusersrespectsusersetpermissions() { global $CFG, $USER, $DB; require_once elispm::lib('data/clusterassignment.class.php'); require_once elispm::lib('data/user.class.php'); require_once elispm::lib('data/userset.class.php'); accesslib_clear_all_caches(true); // Create a user record so that Moodle and PM ids don't match by fluke. set_config('auto_assign_user_idnumber', 0, 'local_elisprogram'); elis::$config = new elis_config(); create_user_record('bogususer', 'Bogususer!0'); // Create our test userset. $userset = new userset(array('name' => 'testuserset')); $userset->save(); // The user who is assigned to the user set. $assigneduser = new user(array('idnumber' => 'assigned', 'username' => 'assigned', 'firstname' => 'assigned', 'lastname' => 'assigned', 'email' => '*****@*****.**', 'country' => 'CA')); $assigneduser->save(); // Userset assignment. $clusterassignment = new clusterassignment(array('clusterid' => $userset->id, 'userid' => $assigneduser->id)); $clusterassignment->save(); // User who is potentially assigning the userset member a new role within the userset. $assigninguser = new user(array('idnumber' => 'assigning', 'username' => 'assigning', 'firstname' => 'assigning', 'lastname' => 'assigning', 'email' => '*****@*****.**', 'country' => 'CA')); $assigninguser->save(); // Need the system context for role assignments. $systemcontext = context_system::instance(); // Set up the role that allows a user to assign roles but only to userset members. $permissionsroleid = create_role('permissionsrole', 'permissionsrole', 'permissionsrole'); // Enable the appropriate capabilities. assign_capability('moodle/role:assign', CAP_ALLOW, $permissionsroleid, $systemcontext->id); assign_capability('local/elisprogram:userset_role_assign_userset_users', CAP_ALLOW, $permissionsroleid, $systemcontext->id); // Perform the role assignment. $moodleuserid = $DB->get_field('user', 'id', array('username' => 'assigning')); role_assign($permissionsroleid, $moodleuserid, $systemcontext->id); // Imitate the user assigned the role which allows for further role assignments only on userset members. $USER = $DB->get_record('user', array('id' => $moodleuserid)); // Test role for potential assignment to userset members. $roleid = create_role('targetrole', 'targetrole', 'targetrole'); // Assign the both users to the userset role. $contextclass = \local_eliscore\context\helper::get_class_for_level(CONTEXT_ELIS_USERSET); $usersetcontext = $contextclass::instance($userset->id); role_assign($roleid, $moodleuserid, $usersetcontext->id); $moodleuserid = $DB->get_field('user', 'id', array('username' => 'assigned')); role_assign($roleid, $moodleuserid, $usersetcontext->id); // Obtain the count of assigned users. $page = new cluster_rolepage(array('id' => $userset->id)); $count = $page->count_role_users($roleid, $usersetcontext); // List should only contain the userset member. $this->assertEquals(1, $count); }
/** * Handle a login event. * * @param string $oidcuniqid A unique identifier for the user. * @param array $authparams Parameters receieved from the auth request. * @param array $tokenparams Parameters received from the token request. * @param \auth_oidc\jwt $idtoken A JWT object representing the received id_token. */ protected function handlelogin($oidcuniqid, $authparams, $tokenparams, $idtoken) { global $DB, $CFG; $tokenrec = $DB->get_record('auth_oidc_token', ['oidcuniqid' => $oidcuniqid]); if (!empty($tokenrec)) { $username = $tokenrec->username; $this->updatetoken($tokenrec->id, $authparams, $tokenparams); } else { // Use 'upn' if available for username (Azure-specific), or fall back to lower-case oidcuniqid. $username = $idtoken->claim('upn'); if (empty($username)) { $username = strtolower($oidcuniqid); } $matchedwith = $this->check_for_matched($username); if (!empty($matchedwith)) { $matchedwith->aadupn = $username; throw new \moodle_exception('errorusermatched', 'local_o365', null, $matchedwith); } $tokenrec = $this->createtoken($oidcuniqid, $username, $authparams, $tokenparams, $idtoken); } $existinguserparams = ['username' => $username, 'mnethostid' => $CFG->mnet_localhost_id]; if ($DB->record_exists('user', $existinguserparams) !== true) { // User does not exist. Create user if site allows, otherwise fail. if (empty($CFG->authpreventaccountcreation)) { $user = create_user_record($username, null, 'oidc'); } else { // Trigger login failed event. $failurereason = AUTH_LOGIN_NOUSER; $eventdata = ['other' => ['username' => $username, 'reason' => $failurereason]]; $event = \core\event\user_login_failed::create($eventdata); $event->trigger(); throw new \moodle_exception('errorauthloginfailednouser', 'auth_oidc'); } } $user = authenticate_user_login($username, null, true); if (empty($user)) { throw new \moodle_exception('errorauthloginfailednouser', 'auth_oidc'); } complete_user_login($user); return true; }
$dbHandle->exec('ALTER TABLE appointments RENAME TO ' . $new_name); $return .= '<li>Renamed existing table <code>appointments</code> to <code>' . $new_name . '</code>.</li>'; } $sqlCreateTable = 'CREATE TABLE users(id INTEGER, uid CHAR(50), fname CHAR(30), lname CHAR(30), email CHAR(200), status INTEGER, description TEXT)'; $dbHandle->exec($sqlCreateTable); $return .= '<li>Created table <code>users</code>.</li>'; $sqlCreateTable = 'CREATE TABLE appointments(id INTEGER PRIMARY KEY AUTOINCREMENT, parent INTEGER, teacher INTEGER, time INTEGER)'; $dbHandle->exec($sqlCreateTable); $return .= '<li>Created table <code>appointments</code>.</li>'; } catch (Exception $e) { $template->throwException($e); } $users = $authHandle->userList(); foreach ($users as $id => $user) { if (!isset($user['description'])) { $user['description'] = ''; } // Lowercase usernames so that there are no case conflicts. $user['uid'] = strtolower($user['uid']); $status = $authHandle->acl($id); create_user_record($id, $user['uid'], $user['fname'], $user['lname'], $user['email'], $status, $user['description']); $return .= '<li>Created user #'; $return .= $id . ' - ' . $user['fname'] . ' ' . $user['lname'] . ' (' . $user['uid'] . ' ' . $user['email'] . ') - ' . $user['description'] . $status; $return .= '</li>'; } create_user_record(-1, '_break', 'Scheduled', 'Break', '*****@*****.**', USER_PARENT, 'Break User'); $return .= '<li>Created break user</li>'; $return .= '</ul>'; $template->setContent($return); $template->render(); $dbHandle = NULL;