<commit_before><?php

/**
 * Copyright 2017 The WildPHP Team
 *
 * You should have received a copy of the MIT license with the project.
 * See the LICENSE file for more information.
 */

namespace WildPHP\Core\Permissions;

use WildPHP\Core\Channels\Channel;
use WildPHP\Core\Connection\IRCMessages\RPL_ISUPPORT;
use WildPHP\Core\EventEmitter;
use WildPHP\Core\Users\User;
use Yoshi2889\Collections\Collection;
use Yoshi2889\Container\ComponentInterface;
use Yoshi2889\Container\ComponentTrait;

class Validator implements ComponentInterface
{
	use ComponentTrait;

	/**
	 * @var array
	 */
	protected $modes = [];

	/**
	 * @var string
	 */
	protected $owner = '';

	/**
	 * @var PermissionGroupCollection
	 */
	protected $permissionGroupCollection;

	/**
	 * Validator constructor.
	 *
	 * @param EventEmitter $eventEmitter
	 * @param PermissionGroupCollection $permissionGroupCollection
	 * @param string $owner
	 */
	public function __construct(EventEmitter $eventEmitter, PermissionGroupCollection $permissionGroupCollection, string $owner)
	{
		$eventEmitter->on('irc.line.in.005', [$this, 'createModeGroups']);

		$this->permissionGroupCollection = $permissionGroupCollection;
		$this->setOwner($owner);
	}

	/**
	 * @param RPL_ISUPPORT $ircMessage
	 */
	public function createModeGroups(RPL_ISUPPORT $ircMessage)
	{
		$variables = $ircMessage->getVariables();

		if (!array_key_exists('prefix', $variables) || !preg_match('/\((.+)\)(.+)/', $variables['prefix'], $out))
			return;

		$modes = str_split($out[1]);
		$this->modes = $modes;

		foreach ($modes as $mode)
		{
			if ($this->permissionGroupCollection->offsetExists($mode))
				continue;

			$permGroup = new PermissionGroup();
			$permGroup->setModeGroup(true);
			$this->permissionGroupCollection->offsetSet($mode, $permGroup);
		}
	}

	/**
	 * @param string $permissionName
	 * @param User $user
	 * @param Channel|null $channel
	 *
	 * @return string|false String with reason on success; boolean false otherwise.
	 */
	public function isAllowedTo(string $permissionName, User $user, ?Channel $channel = null)
	{
		// The order to check in:
		// 0. Is bot owner (has all perms)
		// 1. User OP in channel
		// 2. User Voice in channel
		// 3. User in other group with permission
		if ($user->getIrcAccount() == $this->getOwner())
			return 'owner';

		if (!empty($channel))
		{
			foreach ($this->modes as $mode)
			{
				if (!$channel->getChannelModes()->isUserInMode($mode, $user))
					continue;

				/** @var PermissionGroup $permGroup */
				$permGroup = $this->permissionGroupCollection
					->offsetGet($mode);

				if ($permGroup->hasPermission($permissionName))
					return $mode;
			}
		}

		$channelName = !empty($channel) ? $channel->getName() : '';

		/** @var Collection $groups */
		$groups = $this->permissionGroupCollection
			->filter(function ($item) use ($user)
			{
				/** @var PermissionGroup $item */
				if ($item->isModeGroup())
					return false;

				return $item->getUserCollection()->contains($user->getIrcAccount());
			});

		foreach ((array) $groups as $name => $group)
		{
			/** @var PermissionGroup $group */
			if ($group->hasPermission($permissionName, $channelName))
				return $name;
		}

		return false;
	}

	/**
	 * @return PermissionGroupCollection
	 */
	public function getPermissionGroupCollection(): PermissionGroupCollection
	{
		return $this->permissionGroupCollection;
	}

	/**
	 * @param PermissionGroupCollection $permissionGroupCollection
	 */
	public function setPermissionGroupCollection(PermissionGroupCollection $permissionGroupCollection)
	{
		$this->permissionGroupCollection = $permissionGroupCollection;
	}

	/**
	 * @return array
	 */
	public function getModes(): array
	{
		return $this->modes;
	}

	/**
	 * @return string
	 */
	public function getOwner(): string
	{
		return $this->owner;
	}

	/**
	 * @param string $owner
	 */
	public function setOwner(string $owner)
	{
		$this->owner = $owner;
	}
}<commit_msg>Validator: Make sure the returned group name is a string<commit_after><?php

/**
 * Copyright 2017 The WildPHP Team
 *
 * You should have received a copy of the MIT license with the project.
 * See the LICENSE file for more information.
 */

namespace WildPHP\Core\Permissions;

use WildPHP\Core\Channels\Channel;
use WildPHP\Core\Connection\IRCMessages\RPL_ISUPPORT;
use WildPHP\Core\EventEmitter;
use WildPHP\Core\Users\User;
use Yoshi2889\Collections\Collection;
use Yoshi2889\Container\ComponentInterface;
use Yoshi2889\Container\ComponentTrait;

class Validator implements ComponentInterface
{
	use ComponentTrait;

	/**
	 * @var array
	 */
	protected $modes = [];

	/**
	 * @var string
	 */
	protected $owner = '';

	/**
	 * @var PermissionGroupCollection
	 */
	protected $permissionGroupCollection;

	/**
	 * Validator constructor.
	 *
	 * @param EventEmitter $eventEmitter
	 * @param PermissionGroupCollection $permissionGroupCollection
	 * @param string $owner
	 */
	public function __construct(EventEmitter $eventEmitter, PermissionGroupCollection $permissionGroupCollection, string $owner)
	{
		$eventEmitter->on('irc.line.in.005', [$this, 'createModeGroups']);

		$this->permissionGroupCollection = $permissionGroupCollection;
		$this->setOwner($owner);
	}

	/**
	 * @param RPL_ISUPPORT $ircMessage
	 */
	public function createModeGroups(RPL_ISUPPORT $ircMessage)
	{
		$variables = $ircMessage->getVariables();

		if (!array_key_exists('prefix', $variables) || !preg_match('/\((.+)\)(.+)/', $variables['prefix'], $out))
			return;

		$modes = str_split($out[1]);
		$this->modes = $modes;

		foreach ($modes as $mode)
		{
			if ($this->permissionGroupCollection->offsetExists($mode))
				continue;

			$permGroup = new PermissionGroup();
			$permGroup->setModeGroup(true);
			$this->permissionGroupCollection->offsetSet($mode, $permGroup);
		}
	}

	/**
	 * @param string $permissionName
	 * @param User $user
	 * @param Channel|null $channel
	 *
	 * @return string|false String with reason on success; boolean false otherwise.
	 */
	public function isAllowedTo(string $permissionName, User $user, ?Channel $channel = null)
	{
		// The order to check in:
		// 0. Is bot owner (has all perms)
		// 1. User OP in channel
		// 2. User Voice in channel
		// 3. User in other group with permission
		if ($user->getIrcAccount() == $this->getOwner())
			return 'owner';

		if (!empty($channel))
		{
			foreach ($this->modes as $mode)
			{
				if (!$channel->getChannelModes()->isUserInMode($mode, $user))
					continue;

				/** @var PermissionGroup $permGroup */
				$permGroup = $this->permissionGroupCollection
					->offsetGet($mode);

				if ($permGroup->hasPermission($permissionName))
					return $mode;
			}
		}

		$channelName = !empty($channel) ? $channel->getName() : '';

		/** @var Collection $groups */
		$groups = $this->permissionGroupCollection
			->filter(function ($item) use ($user)
			{
				/** @var PermissionGroup $item */
				if ($item->isModeGroup())
					return false;

				return $item->getUserCollection()->contains($user->getIrcAccount());
			});

		foreach ((array) $groups as $name => $group)
		{
			/** @var PermissionGroup $group */
			if ($group->hasPermission($permissionName, $channelName))
				return (string) $name;
		}

		return false;
	}

	/**
	 * @return PermissionGroupCollection
	 */
	public function getPermissionGroupCollection(): PermissionGroupCollection
	{
		return $this->permissionGroupCollection;
	}

	/**
	 * @param PermissionGroupCollection $permissionGroupCollection
	 */
	public function setPermissionGroupCollection(PermissionGroupCollection $permissionGroupCollection)
	{
		$this->permissionGroupCollection = $permissionGroupCollection;
	}

	/**
	 * @return array
	 */
	public function getModes(): array
	{
		return $this->modes;
	}

	/**
	 * @return string
	 */
	public function getOwner(): string
	{
		return $this->owner;
	}

	/**
	 * @param string $owner
	 */
	public function setOwner(string $owner)
	{
		$this->owner = $owner;
	}
}
{'fraction_non_alphanumeric': 0.14240745404180308, 'fraction_numerical': 0.0060438176781667085, 'mean_word_length': 3.998741346758968, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 67, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1529153', 'n_tokens_mistral': 2710, 'n_tokens_neox': 2336, 'n_words': 568}