示例#1
0
    def is_admin(self):
        if self.is_fake:
            return False

        flags = var.FLAGS[self.rawnick] + var.FLAGS_ACCS[self.account]

        if "F" not in flags:
            try:
                hosts = set(botconfig.ADMINS)
                accounts = set(botconfig.ADMINS_ACCOUNTS)

                if not var.DISABLE_ACCOUNTS and self.account is not None:
                    for pattern in accounts:
                        if fnmatch.fnmatch(lower(self.account), lower(pattern)):
                            return True

                for hostmask in hosts:
                    if self.match_hostmask(hostmask):
                        return True
            except AttributeError:
                pass

            return self.is_owner()

        return True
示例#2
0
 def lower(self):
     temp = type(self)(self.client, lower(self.nick), lower(self.ident),
                       lower(self.host, casemapping="ascii"),
                       lower(self.account))
     if temp is not self:  # If everything is already lowercase, we'll get back the same instance
         temp.channels = self.channels
         temp.ref = self.ref or self
     return temp
示例#3
0
    def match_hostmask(self, hostmask):
        """Match n!u@h, u@h, or just h by itself."""
        nick, ident, host = re.match("(?:(?:(.*?)!)?(.*?)@)?(.*)", hostmask).groups("")
        temp = self.lower()

        return ((not nick or fnmatch.fnmatch(temp.nick, lower(nick))) and
                (not ident or fnmatch.fnmatch(temp.ident, lower(ident))) and
                fnmatch.fnmatch(temp.host, lower(host, casemapping="ascii")))
示例#4
0
def complete_match(pattern: str, scope=None):
    """ Find a user or users who match the given pattern.

    :param pattern: Pattern to match on. The format is "[nick][:account]",
        with [] denoting an optional field. Exact matches are tried, and then
        prefix matches (stripping special characters as needed). If both a nick
        and an account are specified, both must match.
    :param Optional[Iterable[User]] scope: Users to match pattern against. If None,
        search against all users.
    :returns: A Match object describing whether or not the match succeeded.
    :rtype: Match[User]
    """
    if scope is None:
        scope = _users
    matches = []
    nick_search, _, acct_search = lower(pattern).partition(":")
    if not nick_search and not acct_search:
        return Match([])

    direct_match = False
    for user in scope:
        nick = lower(user.nick)
        stripped_nick = nick.lstrip("[{\\^_`|}]")
        if nick_search:
            if nick == nick_search:
                if not direct_match:
                    matches.clear()
                    direct_match = True
                matches.append(user)
            elif not direct_match and (nick.startswith(nick_search) or
                                       stripped_nick.startswith(nick_search)):
                matches.append(user)
        else:
            matches.append(user)

    if acct_search:
        scope = list(matches)
        matches.clear()
        direct_match = False
        for user in scope:
            if not user.account:
                continue  # fakes don't have accounts, so this search won't be able to find them
            acct = lower(user.account)
            stripped_acct = acct.lstrip("[{\\^_`|}]")
            if acct == acct_search:
                if not direct_match:
                    matches.clear()
                    direct_match = True
                matches.append(user)
            elif not direct_match and (acct.startswith(acct_search) or
                                       stripped_acct.startswith(acct_search)):
                matches.append(user)

    return Match(matches)
示例#5
0
 def lower(self):
     temp = type(self)(self.client, lower(self.nick))
     if temp is not self:
         temp.ident = lower(self.ident)
         temp.host = lower(self.host, casemapping="ascii")
         temp.realname = lower(self.realname)
         temp.account = lower(self.account)
         temp.modes = self.modes
         temp.channels = self.channels
         temp.ref = self.ref or self
     return temp
示例#6
0
def complete_match(string, users):
    matches = []
    string = lower(string)
    for user in users:
        nick = lower(user.nick)
        if nick == string:
            return user, 1
        elif nick.startswith(string) or nick.lstrip("[{\\^_`|}]").startswith(string):
            matches.append(user)

    if len(matches) != 1:
        return None, len(matches)

    return matches[0], 1
示例#7
0
def get(name, *, allow_none=False):
    try:
        return _channels[lower(name)]
    except KeyError:
        if allow_none:
            return None
        raise
示例#8
0
文件: channels.py 项目: lykoss/lykos
def get(name, *, allow_none=False):
    try:
        return _channels[lower(name)]
    except KeyError:
        if allow_none:
            return None
        raise
示例#9
0
 def _clear(self):
     for user in self.users:
         del user.channels[self]
     self.users.clear()
     self.modes.clear()
     self.state = _States.Cleared
     self.timestamp = None
     del _channels[lower(self.name)]
示例#10
0
文件: channels.py 项目: lykoss/lykos
 def _clear(self):
     for user in self.users:
         del user.channels[self]
     self.users.clear()
     self.modes.clear()
     self.state = _States.Cleared
     self.timestamp = None
     del _channels[lower(self.name)]
示例#11
0
    def is_owner(self):
        if self.is_fake:
            return False

        hosts = set(botconfig.OWNERS)
        accounts = set(botconfig.OWNERS_ACCOUNTS)

        if not var.DISABLE_ACCOUNTS and self.account is not None:
            for pattern in accounts:
                if fnmatch.fnmatch(lower(self.account), lower(pattern)):
                    return True

        for hostmask in hosts:
            if self.match_hostmask(hostmask):
                return True

        return False
示例#12
0
文件: channels.py 项目: lykoss/lykos
def add(name, cli, key=""):
    """Add and return a new channel, or an existing one if it exists."""

    # We use add() in a bunch of places where the channel probably (but
    # not surely) already exists. If it does, obviously we want to use
    # that one. However, if the client is *not* the same, that means we
    # would be trying to send something from one connection over to
    # another one (or some other weird stuff like that). Instead of
    # jumping through hoops, we just disallow it here.

    if lower(name) in _channels:
        if cli is not _channels[lower(name)].client:
            raise RuntimeError("different IRC client for channel {0}".format(name))
        return _channels[lower(name)]

    cls = Channel
    if predicate(name):
        cls = FakeChannel

    chan = _channels[lower(name)] = cls(name, cli)
    chan._key = key
    chan.join()
    return chan
示例#13
0
def add(name, cli, key=""):
    """Add and return a new channel, or an existing one if it exists."""

    # We use add() in a bunch of places where the channel probably (but
    # not surely) already exists. If it does, obviously we want to use
    # that one. However, if the client is *not* the same, that means we
    # would be trying to send something from one connection over to
    # another one (or some other weird stuff like that). Instead of
    # jumping through hoops, we just disallow it here.

    if lower(name) in _channels:
        if cli is not _channels[lower(name)].client:
            raise RuntimeError(
                "different IRC client for channel {0}".format(name))
        return _channels[lower(name)]

    cls = Channel
    if predicate(name):
        cls = FakeChannel

    chan = _channels[lower(name)] = cls(name, cli)
    chan._key = key
    chan.join()
    return chan
示例#14
0
def exists(name):
    """Return True if a channel by the name exists, False otherwise."""
    return lower(name) in _channels
示例#15
0
文件: channels.py 项目: lykoss/lykos
def exists(name):
    """Return True if a channel by the name exists, False otherwise."""
    return lower(name) in _channels
示例#16
0
def init_vars():
    from src.context import lower
    with var.GRAVEYARD_LOCK:
        conn = _conn()
        c = conn.cursor()
        c.execute("""SELECT
                       pl.account_display,
                       pe.notice,
                       pe.deadchat,
                       pe.pingif,
                       pe.stasis_amount,
                       pe.stasis_expires,
                       COALESCE(at.flags, a.flags)
                     FROM person pe
                     JOIN player pl
                       ON pl.person = pe.id
                     LEFT JOIN access a
                       ON a.person = pe.id
                     LEFT JOIN access_template at
                       ON at.id = a.template
                     WHERE pl.active = 1""")

        var.PREFER_NOTICE_ACCS = set() # Same as above, except accounts. takes precedence
        var.STASISED_ACCS = defaultdict(int)
        var.PING_IF_PREFS_ACCS = {}
        var.PING_IF_NUMS_ACCS = defaultdict(set)
        var.DEADCHAT_PREFS_ACCS = set()
        var.FLAGS_ACCS = defaultdict(str)
        var.DENY_ACCS = defaultdict(set)

        for acc, notice, dc, pi, stasis, stasisexp, flags in c:
            if acc is not None:
                lacc = lower(acc)
                if notice == 1:
                    var.PREFER_NOTICE_ACCS.add(lacc)
                if stasis > 0:
                    var.STASISED_ACCS[lacc] = stasis
                if pi is not None and pi > 0:
                    var.PING_IF_PREFS_ACCS[lacc] = pi
                    var.PING_IF_NUMS_ACCS[pi].add(lacc)
                if dc == 1:
                    var.DEADCHAT_PREFS_ACCS.add(lacc)
                if flags:
                    var.FLAGS_ACCS[lacc] = flags

        c.execute("""SELECT
                       pl.account_display,
                       ws.data
                     FROM warning w
                     JOIN warning_sanction ws
                       ON ws.warning = w.id
                     JOIN person pe
                       ON pe.id = w.target
                     JOIN player pl
                       ON pl.person = pe.id
                     WHERE
                       ws.sanction = 'deny command'
                       AND w.deleted = 0
                       AND (
                         w.expires IS NULL
                         OR w.expires > datetime('now')
                       )""")
        for acc, command in c:
            if acc is not None:
                lacc = lower(acc)
                var.DENY_ACCS[lacc].add(command)
示例#17
0
def _get_ids(acc, add=False, casemap="ascii"):
    from src.context import lower
    conn = _conn()
    c = conn.cursor()
    if acc == "*":
        acc = None
    if acc is None:
        return (None, None)

    ascii_acc = lower(acc, casemapping="ascii")
    rfc1459_acc = lower(acc, casemapping="rfc1459")
    strict_acc = lower(acc, casemapping="strict-rfc1459")

    c.execute("""SELECT pe.id, pl.id, pl.account_display
                 FROM player pl
                 JOIN person pe
                   ON pe.id = pl.person
                 WHERE
                   pl.account_lower_{0} = ?
                   AND pl.active = 1""".format(casemap), (acc,))
    row = c.fetchone()
    peid = None
    plid = None
    if not row:
        # Maybe have an IRC casefolded version of this account in the db
        # Check in order of most restrictive to least restrictive
        # If all three casemappings fail to match, row will still be None
        if casemap == "ascii":
            peid, plid = _get_ids(strict_acc, add=add, casemap="rfc1459_strict")
            row = peid, plid, None
        elif casemap == "rfc1459_strict":
            peid, plid = _get_ids(rfc1459_acc, add=add, casemap="rfc1459")
            row = peid, plid, None

    if row:
        peid, plid, display_acc = row
        if acc != display_acc:
            # normalize case in the db to what it should be
            c.execute("""UPDATE player
                         SET
                           account_display=?,
                           account_lower_ascii=?,
                           account_lower_rfc1459=?,
                           account_lower_rfc1459_strict=?
                         WHERE id=?""",
                      (acc, ascii_acc, rfc1459_acc, strict_acc, row[1]))

            conn.commit()
            # fix up our vars
            init_vars()
    elif add:
        c.execute("""INSERT INTO player
                     (
                       account_display,
                       account_lower_ascii,
                       account_lower_rfc1459,
                       account_lower_rfc1459_strict
                     )
                     VALUES (?, ?, ?, ?)""", (acc, ascii_acc, rfc1459_acc, strict_acc))
        plid = c.lastrowid
        c.execute("INSERT INTO person (primary_player) VALUES (?)", (plid,))
        peid = c.lastrowid
        c.execute("UPDATE player SET person=? WHERE id=?", (peid, plid))
        conn.commit()
    return (peid, plid)
示例#18
0
def irc_lower(nick):
    from src.context import lower
    return lower(nick)
示例#19
0
def irc_lower(nick):  # FIXME: deprecated, use src.context.lower
    from src.context import lower
    return lower(nick)