function handle_facebook_connection_login($current_logged_in_member) { if (!class_exists('ocp_tempcode')) { return NULL; } if (is_guest($current_logged_in_member)) { $current_logged_in_member = NULL; // We are not a normal cookie login so ocPortal has loaded up a Guest session already in the expectation of keeping it. Unsetting it will force a rebind (existing session may be reused though) require_code('users_inactive_occasionals'); set_session_id(-1); } // If already session-logged-in onto a Facebook account, don't bother doing anything if (!is_null($current_logged_in_member) && $GLOBALS['FORUM_DRIVER']->get_member_row_field($current_logged_in_member, 'm_password_compat_scheme') == 'facebook') { return $current_logged_in_member; } // Who is this user, from Facebook's point of view? global $FACEBOOK_CONNECT; $facebook_uid = $FACEBOOK_CONNECT->getUser(); if (is_null($facebook_uid)) { return $current_logged_in_member; } try { $details = $FACEBOOK_CONNECT->api('/me'); } catch (Exception $e) { return $current_logged_in_member; } $details2 = $FACEBOOK_CONNECT->api('/me', array('fields' => 'picture', 'type' => 'normal')); if (!is_array($details) || !is_array($details2)) { return $current_logged_in_member; } $details = array_merge($details, $details2); if (!isset($details['name'])) { return $current_logged_in_member; } $username = $details['name']; $photo_url = array_key_exists('picture', $details) ? $details['picture'] : ''; if (is_array($photo_url)) { $photo_url = $photo_url['data']['url']; } if ($photo_url != '') { $photo_url = 'http://graph.facebook.com/' . strval($facebook_uid) . '/picture?type=large'; // In case URL changes } $avatar_url = $photo_url == '' ? mixed() : $photo_url; $photo_thumb_url = ''; if ($photo_url != '') { $photo_thumb_url = $photo_url; } $email_address = array_key_exists('email', $details) ? $details['email'] : ''; $timezone = mixed(); if (isset($details['timezone'])) { require_code('temporal'); $timezone = convert_timezone_offset_to_formal_timezone($details['timezone']); } $language = mixed(); if (isset($details['locale'])) { $language = strtoupper($details['locale']); } if ($language !== NULL) { if (!file_exists(get_custom_file_base() . '/lang_custom/' . $language)) { $language = preg_replace('#\\_.*$#', '', $language); if (!file_exists(get_custom_file_base() . '/lang_custom/' . $language)) { $language = ''; } } } $dob = array_key_exists('birthday', $details) ? $details['birthday'] : ''; $dob_day = mixed(); $dob_month = mixed(); $dob_year = mixed(); if ($dob != '') { $_dob = explode('/', $dob); $dob_day = intval($_dob[1]); $dob_month = intval($_dob[0]); $dob_year = intval($_dob[2]); } // See if they have logged in before - i.e. have a synched account $member_row = $GLOBALS['FORUM_DB']->query_select('f_members', array('*'), array('m_password_compat_scheme' => 'facebook', 'm_pass_hash_salted' => $facebook_uid), 'ORDER BY id DESC', 1); $member = array_key_exists(0, $member_row) ? $member_row[0]['id'] : NULL; if (is_guest($member)) { $member = NULL; } /*if (!is_null($member)) // Useful for debugging { require_code('ocf_members_action2'); ocf_delete_member($member); $member=NULL; }*/ // If logged in before using Facebook, see if they've changed their name or email or timezone on Facebook -- if so, try and update locally to match if (!is_null($member)) { if (!is_null($current_logged_in_member) && $current_logged_in_member !== NULL && !is_guest($current_logged_in_member) && $current_logged_in_member != $member) { return $current_logged_in_member; } // User has an active login, and the Facebook account is bound to a DIFFERENT login. Take precedence to the other login that is active on top of this $last_visit_time = $member[0]['m_last_visit_time']; if ($timezone !== NULL) { if (tz_time(time(), $timezone) == tz_time(time(), $member[0]['m_timezone_offset'])) { $timezone = $member[0]['m_timezone_offset']; } // If equivalent, don't change } $test = $GLOBALS['FORUM_DB']->query_value_null_ok('f_members', 'id', array('m_username' => $username)); if (!is_null($test)) { $update_map = array('m_username' => $username, 'm_dob_day' => $dob_day, 'm_dob_month' => $dob_month, 'm_dob_year' => $dob_year); if ($email_address != '') { $update_map['m_email_address'] = $email_address; } if ($avatar_url !== NULL && ($test == '' || strpos($test, 'facebook') !== false || strpos($test, 'fbcdn') !== false)) { if ($timezone !== NULL) { $update_map['m_timezone_offset'] = $timezone; } $update_map['m_avatar_url'] = $avatar_url; $update_map['m_photo_url'] = $photo_url; $update_map['m_photo_thumb_url'] = $photo_thumb_url; } $GLOBALS['FORUM_DB']->query_update('f_members', $update_map, array('m_password_compat_scheme' => 'facebook', 'm_pass_hash_salted' => strval($facebook_uid)), '', 1); if ($username != $member[0]['m_username']) { // Fix cacheing for usernames $to_fix = array('f_forums/f_cache_last_username', 'f_posts/p_poster_name_if_guest', 'f_topics/t_cache_first_username', 'f_topics/t_cache_last_username'); foreach ($to_fix as $fix) { list($table, $field) = explode('/', $fix); $GLOBALS['FORUM_DB']->query_update($table, array($field => $username), array($field => $member[0]['m_username'])); } } } } // Not logged in before using Facebook, so we need to create an account, or bind to the active ocPortal login if there is one $in_a_sane_place = get_page_name() != 'login' && (running_script('index') || running_script('execute_temp')); // If we're in some weird script, or the login module UI, it's not a sane place, don't be doing account creation yet if (is_null($member) && $in_a_sane_place) { // Bind to existing ocPortal login? if (!is_null($current_logged_in_member)) { /*if (post_param_integer('associated_confirm',0)==0) Won't work because Facebook is currently done in JS and cookies force this. If user wishes to cancel they must go to http://www.facebook.com/settings?tab=applications and remove the app, then run a lost password reset. { $title=get_page_title('LOGIN_FACEBOOK_HEADER'); $message=do_lang_tempcode('LOGGED_IN_SURE_FACEBOOK',escape_html($GLOBALS['FORUM_DRIVER']->get_username($current_logged_in_member))); $middle=do_template('YESNO_SCREEN',array('TITLE'=>$title,'TEXT'=>$message,'HIDDEN'=>form_input_hidden('associated_confirm','1'),'URL'=>get_self_url_easy())); $tpl=globalise($middle,NULL,'',true); $tpl->evaluate_echo(); exit(); }*/ $GLOBALS['FORUM_DB']->query_update('f_members', array('m_password_compat_scheme' => 'facebook', 'm_pass_hash_salted' => $facebook_uid), array('id' => $current_logged_in_member), '', 1); require_code('site'); require_lang('facebook'); attach_message(do_lang_tempcode('FACEBOOK_ACCOUNT_CONNECTED', escape_html(get_site_name()), escape_html($GLOBALS['FORUM_DRIVER']->get_username($current_logged_in_member)), array(escape_html($username))), 'inform'); return $current_logged_in_member; } // If we're still here, we have to create a new account... // ------------------------------------------------------- $completion_form_submitted = post_param('email_address', '') != ''; // If there's a conflicting username, we may need to change it (suffix a number) require_code('ocf_members_action2'); $username = get_username_from_human_name($username); // Ask ocP to finish off the profile from the information presented in the POST environment (a standard mechanism in ocPortal, for third party logins of various kinds) require_lang('ocf'); require_code('ocf_members'); require_code('ocf_groups'); require_code('ocf_members2'); require_code('ocf_members_action'); $_custom_fields = ocf_get_all_custom_fields_match(ocf_get_all_default_groups(true), NULL, NULL, NULL, 1); if (!$completion_form_submitted && count($_custom_fields) != 0 && get_value('no_finish_profile') !== '1') { $GLOBALS['FACEBOOK_FINISHING_PROFILE'] = true; $middle = ocf_member_external_linker_ask($username, 'facebook', $email_address, $dob_day, $dob_month, $dob_year); $tpl = globalise($middle, NULL, '', true); $tpl->evaluate_echo(); exit; } else { $username = post_param('username', $username); if (count($_custom_fields) != 0 && get_value('no_finish_profile') !== '1') { // Was not auto-generated, so needs to be checked ocf_check_name_valid($username, NULL, NULL); } $member = ocf_member_external_linker($username, $facebook_uid, 'facebook', false, $email_address, $dob_day, $dob_month, $dob_year, $timezone, $language, $avatar_url, $photo_url, $photo_thumb_url); } } if (!is_null($member)) { require_code('users_inactive_occasionals'); create_session($member, 1, isset($_COOKIE[get_member_cookie() . '_invisible']) && $_COOKIE[get_member_cookie() . '_invisible'] == '1'); // This will mark it as confirmed } return $member; }
/** * Check a username is valid for adding, and possibly also the password. * * @param SHORT_TEXT The username (may get altered). * @param ?MEMBER The member (NULL: member not actually added yet; this ID is only given for the duplication check, to make sure it doesn't think we are duplicating with ourself). * @param ?SHORT_TEXT The password (NULL: nothing to check). * @param boolean Whether to return errors instead of dieing on them. * @return ?tempcode Error (NULL: none). */ function ocf_check_name_valid(&$username, $member_id = NULL, $password = NULL, $return_errors = false) { /* $striped_username=$username; This would be an internationalisation mistake $allowed_characters=array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z', 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z', '0','1','2','3','4','5','6','7','8','9',' ', '#','@',':',';','/',"\\",'.',',','|','!','%','$','^','(','*',')','-','_','+','=','[',']','{','}','~'); foreach ($allowed_characters as $allowed_character) { $striped_username=str_replace($allowed_character,'',$striped_username); } if ($striped_username!='') warn_exit(do_lang_tempcode('USERNAME_BAD_SYMBOLS'));*/ // Check it doesn't already exist $test = is_null($member_id) ? NULL : $GLOBALS['FORUM_DB']->query_value_null_ok('f_members', 'id', array('m_username' => $username, 'id' => $member_id)); // Precedence on an ID match in case there are duplicate usernames and user is trying to fix that if (is_null($test)) { $test = $GLOBALS['FORUM_DB']->query_value_null_ok('f_members', 'id', array('m_username' => $username)); } if (!is_null($test) && $test !== $member_id) { if (get_option('signup_fullname') == '0') { if ($return_errors) { return do_lang_tempcode('USERNAME_ALREADY_EXISTS'); } warn_exit(do_lang_tempcode('USERNAME_ALREADY_EXISTS')); } else { $username = get_username_from_human_name($username); } } $username_changed = is_null($test); // Check for disallowed symbols in username $disallowed_characters = array(); foreach ($disallowed_characters as $disallowed_character) { if (strpos($username, $disallowed_character) !== false && $username_changed) { if ($return_errors) { return do_lang_tempcode('USERNAME_BAD_SYMBOLS'); } warn_exit(do_lang_tempcode('USERNAME_BAD_SYMBOLS')); } } if (strpos($username, '@') !== false && strpos($username, '.') !== false && $username_changed) { if ($return_errors) { return do_lang_tempcode('USERNAME_BAD_SYMBOLS'); } warn_exit(do_lang_tempcode('USERNAME_BAD_SYMBOLS')); } // Check lengths if (get_page_name() != 'admin_ocf_join') { $_maximum_username_length = get_option('maximum_username_length', true); if (is_null($_maximum_username_length)) { $maximum_username_length = 15; } else { $maximum_username_length = intval($_maximum_username_length); } if (ocp_mb_strlen($username) > $maximum_username_length && $username_changed) { if ($return_errors) { return do_lang_tempcode('USERNAME_TOO_LONG', integer_format($maximum_username_length)); } warn_exit(do_lang_tempcode('USERNAME_TOO_LONG', integer_format($maximum_username_length))); } $_minimum_username_length = get_option('minimum_username_length', true); if (is_null($_minimum_username_length)) { $minimum_username_length = 1; } else { $minimum_username_length = intval($_minimum_username_length); } if (ocp_mb_strlen($username) < $minimum_username_length && $username_changed) { if ($return_errors) { return do_lang_tempcode('USERNAME_TOO_SHORT', integer_format($minimum_username_length)); } warn_exit(do_lang_tempcode('USERNAME_TOO_SHORT', integer_format($minimum_username_length))); } if (!is_null($password)) { $_maximum_password_length = get_option('maximum_password_length', true); if (is_null($_maximum_password_length)) { $maximum_password_length = 1000; } else { $maximum_password_length = intval($_maximum_password_length); } if (ocp_mb_strlen($password) > $maximum_password_length) { if ($return_errors) { return do_lang_tempcode('PASSWORD_TOO_LONG', integer_format($maximum_password_length)); } warn_exit(do_lang_tempcode('PASSWORD_TOO_LONG', integer_format($maximum_password_length))); } $_minimum_password_length = get_option('minimum_password_length', true); if (is_null($_minimum_password_length)) { $minimum_password_length = 1; } else { $minimum_password_length = intval($_minimum_password_length); } if (ocp_mb_strlen($password) < $minimum_password_length) { if ($return_errors) { return do_lang_tempcode('PASSWORD_TOO_SHORT', integer_format($minimum_password_length)); } warn_exit(do_lang_tempcode('PASSWORD_TOO_SHORT', integer_format($minimum_password_length))); } } } // Check for whitespace if (get_option('signup_fullname') == '0') { $prohibit_username_whitespace = get_option('prohibit_username_whitespace', true); if ($prohibit_username_whitespace === '1' && preg_match('#\\s#', $username) != 0 && $username_changed) { if ($return_errors) { return do_lang_tempcode('USERNAME_PASSWORD_WHITESPACE'); } warn_exit(do_lang_tempcode('USERNAME_PASSWORD_WHITESPACE')); } } $prohibit_password_whitespace = get_option('prohibit_password_whitespace', true); if ($prohibit_password_whitespace === '1' && preg_match('#\\s#', $password) != 0 && $username_changed) { if ($return_errors) { return do_lang_tempcode('USERNAME_PASSWORD_WHITESPACE'); } warn_exit(do_lang_tempcode('USERNAME_PASSWORD_WHITESPACE')); } // Check against restricted usernames if (get_page_name() != 'admin_ocf_join' && $username_changed) { $restricted_usernames = explode(',', get_option('restricted_usernames')); $restricted_usernames[] = do_lang('GUEST'); $restricted_usernames[] = do_lang('UNKNOWN'); $restricted_usernames[] = do_lang('SYSTEM'); foreach ($restricted_usernames as $_restricted_username) { $restricted_username = trim($_restricted_username); if ($restricted_username == '') { continue; } if (strpos($username, $restricted_username) !== false) { if ($return_errors) { return do_lang_tempcode('USERNAME_BAD_SUBSTRING'); } warn_exit(do_lang_tempcode('USERNAME_BAD_SUBSTRING')); } } } // Check it is not numeric if (is_numeric($username)) { if ($return_errors) { return do_lang_tempcode('USERNAME_NUMERIC'); } warn_exit(do_lang_tempcode('USERNAME_NUMERIC')); } return NULL; }