Fixed User IP Check Inaccurate

Jeremy P

XenForo developer
Staff member
When in the Admin Control Panel, viewing a user's logged IPs, you have the option to search for more users with the same IP. However, in some cases the search returns no results, even when there are multiple users with the same IP.

Haven't been able to track this down but I can confirm that the IPs are logged for multiple in the xf_ip table, and show up in the ACP when viewing the members individually, but do not appear when running the check.
 
Could you clarify 'in some cases'? Are you saying that it works in some cases and not others?

I took a random sample of a few users that I know should have the same IP address. Also, I took another sample of those that shouldn't and it seems to be working as designed.
 
I don't have this problem on my forum.

I examined the code. The second action which fails to return any records (XenForo_ControllerAdmin_User::actionIpUsers) does an INNER JOIN on xf_user and xf_user_profile. So if either record is missing then the user will be omitted, but that would also cause an error when accessing the user's profile in the Admin CP which you are obviously able to do.

If you have this problem with addons disabled then I will need to take a look for myself. I need a URL and admin login, access to phpmyadmin, and a specific test case that I can work with.
 
Bug confirmed. Here is a fix:

library/XenForo/Model/User.php

Add the red code:

Rich (BB code):
	public function getUsersByIp($ip, array $fetchOptions = array())
	{
		if (!$ip)
		{
			return array();
		}
		else if (is_string($ip) && strpos($ip, '.'))
		{
			$ip = ip2long($ip);
			$ip = sprintf('%u', $ip);
		}

		$orderClause = $this->prepareUserOrderOptions($fetchOptions, 'user.username');

		$joinOptions = $this->prepareUserFetchOptions($fetchOptions);

		return $this->fetchAllKeyed('
			SELECT user.*, ip.ip, MAX(ip.log_date) AS log_date
				' . $joinOptions['selectFields'] . '
				FROM xf_ip AS ip
				INNER JOIN xf_user AS user ON
					(user.user_id = ip.user_id)
				' . $joinOptions['joinTables'] . '
				WHERE ip.ip = ?
				GROUP BY ip.user_id
				' . $orderClause . '
		', 'user_id', $ip);
	}

That converts it to an unsigned integer which is what is stored in the database.
 
Top Bottom