Ejemplo n.º 1
0
def test_channel_has_privilege():
    channel = target.Channel(Identifier('#chan'))
    user = target.User(Identifier('TestUser'), 'example', 'example.com')

    # unknown user
    assert not channel.has_privilege(user.nick, plugin.VOICE)
    assert not channel.has_privilege(user.nick, plugin.OP)

    # user added without privileges
    channel.add_user(user)
    assert not channel.has_privilege(user.nick, plugin.VOICE)
    assert not channel.has_privilege(user.nick, plugin.OP)

    # user added with VOICE privilege
    channel.add_user(user, plugin.VOICE)
    assert channel.has_privilege(user.nick, plugin.VOICE)
    assert not channel.has_privilege(user.nick, plugin.OP)

    # user added with OP privilege
    channel.add_user(user, plugin.OP)
    assert channel.has_privilege(user.nick, plugin.VOICE)
    assert channel.has_privilege(user.nick, plugin.OP)

    # user added with both VOICE & OP privilege
    channel.add_user(user, plugin.VOICE | plugin.OP)
    assert channel.has_privilege(user.nick, plugin.VOICE)
    assert channel.has_privilege(user.nick, plugin.OP)
Ejemplo n.º 2
0
def track_notify(bot, trigger):
    """Track users going away or coming back."""
    if trigger.nick not in bot.users:
        bot.users[trigger.nick] = target.User(trigger.nick, trigger.user,
                                              trigger.host)
    user = bot.users[trigger.nick]
    user.away = bool(trigger.args)
Ejemplo n.º 3
0
def track_join(bot, trigger):
    channel = trigger.sender

    # is it a new channel?
    if channel not in bot.channels:
        LOGGER.info('Channel joined: %s', channel)
        bot.privileges[channel] = dict()
        bot.channels[channel] = target.Channel(channel)

    # did *we* just join?
    if trigger.nick == bot.nick:
        if bot.settings.core.throttle_join:
            LOGGER.debug('JOIN event added to queue for channel: %s', channel)
            bot.memory['join_events_queue'].append(channel)
        else:
            LOGGER.debug('Send direct WHO for channel: %s', channel)
            _send_who(bot, channel)

    # set initial values
    bot.privileges[channel][trigger.nick] = 0

    user = bot.users.get(trigger.nick)
    if user is None:
        user = target.User(trigger.nick, trigger.user, trigger.host)
        bot.users[trigger.nick] = user
    bot.channels[channel].add_user(user)

    if len(trigger.args) > 1 and trigger.args[1] != '*' and (
            'account-notify' in bot.enabled_capabilities
            and 'extended-join' in bot.enabled_capabilities):
        user.account = trigger.args[1]
Ejemplo n.º 4
0
def account_notify(bot, trigger):
    if trigger.nick not in bot.users:
        bot.users[trigger.nick] = target.User(trigger.nick, trigger.user,
                                              trigger.host)
    account = trigger.args[0]
    if account == '*':
        account = None
    bot.users[trigger.nick].account = account
Ejemplo n.º 5
0
def track_notify(bot, trigger):
    """Track users going away or coming back."""
    if trigger.nick not in bot.users:
        bot.users[trigger.nick] = target.User(trigger.nick, trigger.user,
                                              trigger.host)
    user = bot.users[trigger.nick]
    user.away = bool(trigger.args)
    state_change = 'went away' if user.away else 'came back'
    LOGGER.info("User %s: %s", state_change, trigger.nick)
Ejemplo n.º 6
0
def test_channel_is_priv_level_unknown_user():
    channel = target.Channel(Identifier('#chan'))
    user = target.User(Identifier('TestUser'), 'example', 'example.com')

    assert not channel.is_oper(user.nick)
    assert not channel.is_owner(user.nick)
    assert not channel.is_admin(user.nick)
    assert not channel.is_op(user.nick)
    assert not channel.is_halfop(user.nick)
    assert not channel.is_voiced(user.nick)
Ejemplo n.º 7
0
def account_notify(bot, trigger):
    """Track users' accounts."""
    if trigger.nick not in bot.users:
        bot.users[trigger.nick] = target.User(trigger.nick, trigger.user,
                                              trigger.host)
    account = trigger.args[0]
    if account == '*':
        account = None
    bot.users[trigger.nick].account = account
    LOGGER.info("Update account for nick %r: %s", trigger.nick, account)
Ejemplo n.º 8
0
def test_channel_add_user_voiced():
    channel = target.Channel(Identifier('#chan'))
    user = target.User(Identifier('TestUser'), 'example', 'example.com')

    channel.add_user(user, plugin.VOICE)

    assert user.nick in channel.users
    assert channel.users[user.nick] is user

    assert user.nick in channel.privileges
    assert channel.privileges[user.nick] == plugin.VOICE
Ejemplo n.º 9
0
def handle_names(bot, trigger):
    """Handle NAMES responses.

    This function keeps track of users' privileges when Sopel joins channels.
    """
    # TODO specific to one channel type. See issue 281.
    channels = re.search(r'(#\S*)', trigger.raw)
    if not channels:
        return
    channel = Identifier(channels.group(1))
    if channel not in bot.channels:
        bot.channels[channel] = target.Channel(channel)

    # This could probably be made flexible in the future, but I don't think
    # it'd be worth it.
    # If this ever needs to be updated, remember to change the mode handling in
    # the WHO-handler functions below, too.
    mapping = {
        "+": plugin.VOICE,
        "%": plugin.HALFOP,
        "@": plugin.OP,
        "&": plugin.ADMIN,
        "~": plugin.OWNER,
        "!": plugin.OPER,
    }

    uhnames = 'UHNAMES' in bot.isupport
    userhost_in_names = 'userhost-in-names' in bot.enabled_capabilities

    names = trigger.split()
    for name in names:
        if uhnames or userhost_in_names:
            name, mask = name.rsplit('!', 1)
            username, hostname = mask.split('@', 1)
        else:
            username = hostname = None

        priv = 0
        for prefix, value in mapping.items():
            if prefix in name:
                priv = priv | value

        nick = Identifier(name.lstrip(''.join(mapping.keys())))
        user = bot.users.get(nick)
        if user is None:
            # The username/hostname will be included in a NAMES reply only if
            # userhost-in-names is available. We can use them if present.
            # Fortunately, the user should already exist in bot.users by the
            # time this code runs, so this is 99.9% ass-covering.
            user = target.User(nick, username, hostname)
            bot.users[nick] = user
        bot.channels[channel].add_user(user, privs=priv)
Ejemplo n.º 10
0
def test_channel_add_user():
    channel = target.Channel(Identifier('#chan'))
    user = target.User(Identifier('TestUser'), 'example', 'example.com')

    channel.add_user(user)

    assert user.nick in channel.users
    assert channel.users[user.nick] is user

    assert user.nick in channel.privileges
    assert channel.privileges[user.nick] == 0

    assert channel.name in user.channels
Ejemplo n.º 11
0
def test_channel_add_user_replace():
    channel = target.Channel(Identifier('#chan'))
    user = target.User(Identifier('TestUser'), 'example', 'example.com')

    channel.add_user(user, plugin.VOICE)
    channel.add_user(user, plugin.OP)

    assert user.nick in channel.users
    assert channel.users[user.nick] is user

    assert user.nick in channel.privileges
    assert channel.privileges[user.nick] == plugin.OP
    assert channel.privileges[user.nick] & plugin.VOICE == 0, (
        'This user must be replaced, without previous privileges')
Ejemplo n.º 12
0
def handle_names(bot, trigger):
    """Handle NAMES responses.

    This function keeps track of users' privileges when Sopel joins channels.
    """
    names = trigger.split()

    # TODO specific to one channel type. See issue 281.
    channels = re.search(r'(#\S*)', trigger.raw)
    if not channels:
        return
    channel = Identifier(channels.group(1))
    if channel not in bot.privileges:
        bot.privileges[channel] = {}
    if channel not in bot.channels:
        bot.channels[channel] = target.Channel(channel)

    # This could probably be made flexible in the future, but I don't think
    # it'd be worth it.
    # If this ever needs to be updated, remember to change the mode handling in
    # the WHO-handler functions below, too.
    mapping = {
        "+": module.VOICE,
        "%": module.HALFOP,
        "@": module.OP,
        "&": module.ADMIN,
        "~": module.OWNER,
        "!": module.OPER,
    }

    for name in names:
        priv = 0
        for prefix, value in iteritems(mapping):
            if prefix in name:
                priv = priv | value
        nick = Identifier(name.lstrip(''.join(mapping.keys())))
        bot.privileges[channel][nick] = priv
        user = bot.users.get(nick)
        if user is None:
            # It's not possible to set the username/hostname from info received
            # in a NAMES reply, unfortunately.
            # Fortunately, the user should already exist in bot.users by the
            # time this code runs, so this is 99.9% ass-covering.
            user = target.User(nick, None, None)
            bot.users[nick] = user
        bot.channels[channel].add_user(user, privs=priv)
Ejemplo n.º 13
0
def recv_chghost(bot, trigger):
    """Track user/host changes."""
    if trigger.nick not in bot.users:
        bot.users[trigger.nick] = target.User(trigger.nick, trigger.user,
                                              trigger.host)

    try:
        new_user, new_host = trigger.args
    except ValueError:
        LOGGER.warning("Ignoring CHGHOST command with %s arguments: %r",
                       'extra' if len(trigger.args) > 2 else 'insufficient',
                       trigger.args)
        return

    bot.users[trigger.nick].user = new_user
    bot.users[trigger.nick].host = new_host
    LOGGER.info("Update user@host for nick %r: %s@%s", trigger.nick, new_user,
                new_host)
Ejemplo n.º 14
0
def _record_who(bot,
                channel,
                user,
                host,
                nick,
                account=None,
                away=None,
                modes=None):
    nick = Identifier(nick)
    channel = Identifier(channel)
    if nick not in bot.users:
        usr = target.User(nick, user, host)
        bot.users[nick] = usr
    else:
        usr = bot.users[nick]
        # check for & fill in sparse User added by handle_names()
        if usr.host is None and host:
            usr.host = host
        if usr.user is None and user:
            usr.user = user
    if account == '0':
        usr.account = None
    else:
        usr.account = account
    if away is not None:
        usr.away = away
    priv = 0
    if modes:
        mapping = {
            "+": module.VOICE,
            "%": module.HALFOP,
            "@": module.OP,
            "&": module.ADMIN,
            "~": module.OWNER,
            "!": module.OPER,
        }
        for c in modes:
            priv = priv | mapping[c]
    if channel not in bot.channels:
        bot.channels[channel] = target.Channel(channel)
    bot.channels[channel].add_user(usr, privs=priv)
    if channel not in bot.privileges:
        bot.privileges[channel] = {}
    bot.privileges[channel][nick] = priv
Ejemplo n.º 15
0
def track_join(bot, trigger):
    """Track users joining channels.

    When a user joins a channel, the bot will send (or queue) a ``WHO`` command
    to know more about said user (privileges, modes, etc.).
    """
    channel = trigger.sender

    # is it a new channel?
    if channel not in bot.channels:
        bot.privileges[channel] = {}
        bot.channels[channel] = target.Channel(channel)

    # did *we* just join?
    if trigger.nick == bot.nick:
        LOGGER.info("Channel joined: %s", channel)
        if bot.settings.core.throttle_join:
            LOGGER.debug("JOIN event added to queue for channel: %s", channel)
            bot.memory['join_events_queue'].append(channel)
        else:
            LOGGER.debug("Send MODE and direct WHO for channel: %s", channel)
            bot.write(["MODE", channel])
            _send_who(bot, channel)
    else:
        LOGGER.info("Channel %r joined by user: %s", str(channel),
                    trigger.nick)

    # set initial values
    bot.privileges[channel][trigger.nick] = 0

    user = bot.users.get(trigger.nick)
    if user is None:
        user = target.User(trigger.nick, trigger.user, trigger.host)
        bot.users[trigger.nick] = user
    bot.channels[channel].add_user(user)

    if len(trigger.args) > 1 and trigger.args[1] != '*' and (
            'account-notify' in bot.enabled_capabilities
            and 'extended-join' in bot.enabled_capabilities):
        user.account = trigger.args[1]
Ejemplo n.º 16
0
def track_notify(bot, trigger):
    if trigger.nick not in bot.users:
        bot.users[trigger.nick] = target.User(trigger.nick, trigger.user,
                                              trigger.host)
    user = bot.users[trigger.nick]
    user.away = bool(trigger.args)