Example #1
0
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;
}