Beispiel #1
0
    def usaco_account(self, event, user, usaco_user, password):
        if password:
            self._redact(event, password)

        if event.public and password:
            event.addresponse(u"Giving your password in public is bad! Please tell me that again in a private message.")
            return

        if not event.account:
            event.addresponse(u'Sorry, you need to create an account with me first (type "usage accounts" to see how)')
            return
        admin = auth_responses(event, u'usacoadmin')
        if user.lower() == 'i':
            if password is None and not admin:
                event.addresponse(u'Sorry, I need your USACO password to verify your account')
            if password and not self._check_login(user, password):
                event.addresponse(u'Sorry, that account is invalid')
                return
            account = event.session.query(Account).get(event.account)
        else:
            if not admin:
                event.addresponse(event.complain)
                return
            account = event.session.query(Account).filter_by(username=user).first()
            if account is None:
                event.addresponse(u"I don't know who %s is", user)
                return

        try:
            monitor_url = self._get_monitor_url()
        except UsacoException, e:
            event.addresponse(e)
            return
Beispiel #2
0
    def remove(self, event, user, source, username):
        if not username:
            account = event.session.query(Account).get(event.account)
        else:
            if not auth_responses(event, "accounts"):
                return
            account = event.session.query(Account).filter_by(username=username).first()
            if not account:
                event.addresponse(u"I don't know who %s is", username)
                return

        identity = event.session.query(Identity).filter_by(account_id=account.id, identity=user, source=source).first()
        if not identity:
            event.addresponse(u"I don't know about that identity")
        else:
            identity.account_id = None
            event.session.add(identity)
            event.session.commit()

            identify_cache.clear()

            event.addresponse(True)
            log.info(
                u"Removed identity %s (%s on %s) from account %s (%s) by %s/%s (%s)",
                identity.id,
                identity.identity,
                identity.source,
                account.id,
                account.username,
                event.account,
                event.identity,
                event.sender["connection"],
            )
Beispiel #3
0
    def attribute(self, event, username, name, value):

        if username.lower() == "my":
            if not event.account:
                event.addresponse(u"I don't know who you are")
                return
            account = event.session.query(Account).get(event.account)
            if not account:
                event.addresponse(u"%s doesn't exist. Please use 'add account' first", username)
                return

        else:
            if not auth_responses(event, "accounts"):
                return
            account = event.session.query(Account).filter_by(username=username).first()
            if not account:
                event.addresponse(u"I don't know who %s is", username)
                return

        account.attributes.append(Attribute(name, value))
        event.session.add(account)
        event.session.commit()

        event.addresponse(True)
        log.info(
            u"Added attribute '%s' = '%s' to account %s (%s) by %s/%s (%s)",
            name,
            value,
            account.id,
            account.username,
            event.account,
            event.identity,
            event.sender["connection"],
        )
Beispiel #4
0
    def remove(self, event, user, source, username):
        if not username:
            account = event.session.query(Account).get(event.account)
        else:
            if not auth_responses(event, 'accounts'):
                return
            account = event.session.query(Account) \
                    .filter_by(username=username).first()
            if not account:
                event.addresponse(u"I don't know who %s is", username)
                return

        identity = event.session.query(Identity) \
                .filter_by(account_id=account.id, identity=user,
                           source=source).first()
        if not identity:
            event.addresponse(u"I don't know about that identity")
        else:
            identity.account_id = None
            event.session.save_or_update(identity)
            event.session.commit()

            identify_cache.clear()

            event.addresponse(True)
            log.info(
                u"Removed identity %s (%s on %s) from account %s (%s) by %s/%s (%s)",
                identity.id, identity.identity, identity.source, account.id,
                account.username, event.account, event.identity,
                event.sender['connection'])
Beispiel #5
0
    def usaco_account(self, event, user, usaco_user, password):
        if password:
            self._redact(event, password)

        if event.public and password:
            event.addresponse(u"Giving your password in public is bad! Please tell me that again in a private message.")
            return

        if not event.account:
            event.addresponse(u'Sorry, you need to create an account with me first (type "usage accounts" to see how)')
            return
        admin = auth_responses(event, u'usacoadmin')
        if user.lower() == 'i':
            if password is None and not admin:
                event.addresponse(u'Sorry, I need your USACO password to verify your account')
            if password and not self._check_login(user, password):
                event.addresponse(u'Sorry, that account is invalid')
                return
            account = event.session.query(Account).get(event.account)
        else:
            if not admin:
                event.addresponse(event.complain)
                return
            account = event.session.query(Account).filter_by(username=user).first()
            if account is None:
                event.addresponse(u"I don't know who %s is", user)
                return

        try:
            monitor_url = self._get_monitor_url()
        except UsacoException, e:
            event.addresponse(e)
            return
Beispiel #6
0
    def attribute(self, event, username, name, value):

        if username.lower() == 'my':
            if not event.account:
                event.addresponse(u"I don't know who you are")
                return
            account = event.session.query(Account).get(event.account)
            if not account:
                event.addresponse(
                    u"%s doesn't exist. Please use 'add account' first",
                    username)
                return

        else:
            if not auth_responses(event, 'accounts'):
                return
            account = event.session.query(Account) \
                    .filter_by(username=username).first()
            if not account:
                event.addresponse(u"I don't know who %s is", username)
                return

        account.attributes.append(Attribute(name, value))
        event.session.save_or_update(account)
        event.session.commit()

        event.addresponse(True)
        log.info(
            u"Added attribute '%s' = '%s' to account %s (%s) by %s/%s (%s)",
            name, value, account.id, account.username, event.account,
            event.identity, event.sender['connection'])
Beispiel #7
0
    def set_factoid(self, event, correction, name, addition1, verb1, verb2,
                    addition2, value):
        verb = verb1 or verb2
        addition = addition1 or addition2

        name = strip_name(name)

        if name == u'':
            event.addresponse(u"Sorry, I'm not interested in empty factoids")
            return

        if name.lower() in self.interrogatives:
            event.addresponse(
                choice((
                    u"I'm afraid I have no idea",
                    u"Not a clue, sorry",
                    u"Erk, dunno",
                )))
            return

        factoid = event.session.query(Factoid).join(Factoid.names)\
                .filter(FactoidName.name==escape_name(name)).first()
        if factoid:
            if correction:
                identities = get_identities(event)
                if not auth_responses(event, u'factoidadmin') and len(
                        filter(lambda x: x.identity_id not in identities,
                               factoid.values)) > 0:
                    return
                for fvalue in factoid.values:
                    event.session.delete(fvalue)
            elif not addition:
                event.addresponse(u'I already know stuff about %s', name)
                return
        else:
            factoid = Factoid()
            fname = FactoidName(unicode(name), event.identity)
            factoid.names.append(fname)
            event.session.add(factoid)
            event.session.flush()
            log.info(u"Creating factoid %s with name '%s' by %s", factoid.id,
                     fname.name, event.identity)

        if not reply_re.match(value) and not action_re.match(value):
            value = '%s %s' % (verb, value)
        fvalue = FactoidValue(unicode(value), event.identity)
        factoid.values.append(fvalue)
        event.session.add(factoid)
        event.session.commit()
        self.last_set_factoid = factoid.names[0].name
        log.info(u"Added value '%s' to factoid %s (%s) by %s/%s (%s)",
                 fvalue.value, factoid.id, factoid.names[0].name,
                 event.account, event.identity, event.sender['connection'])
        event.addresponse(
            choice((
                u'If you say so',
                u'One learns a new thing every day',
                u"I'll remember that",
                u'Got it',
            )))
Beispiel #8
0
    def get(self, event, key):
        if 'password' in key.lower() and not auth_responses(event, u'config'):
            return

        option = self.find_option(key)
        if isinstance(option, dict):
            config = option
            key = ''
        elif option is not None:
            config = option[0].__get__(option[1], type(option[1]))
            key = option[2]
        elif key == 'plugins':
            # Construct a dictionary since this isn't a list-valued option,
            # but a list of option keys.
            config = dict((plugin, None) for plugin in list_plugins())
            key = ''
        elif key == 'sources':
            config = ibid.sources
            key = ''
        else:
            config = ibid.config

        if key:
            for part in key.split('.'):
                if not isinstance(config, dict) or part not in config:
                    event.addresponse(u'No such option')
                    return
                config = config[part]

        if isinstance(config, list):
            event.addresponse(u', '.join(config))
        elif isinstance(config, dict):
            event.addresponse(u'Keys: ' + human_join(config.keys()))
        else:
            event.addresponse(unicode(config))
Beispiel #9
0
    def set_factoid(self, event, correction, name, addition1, verb1, verb2, addition2, value):
        verb = verb1 or verb2
        addition = addition1 or addition2

        name = strip_name(name)

        if name == u'':
            event.addresponse(u"Sorry, I'm not interested in empty factoids")
            return

        if name.lower() in self.interrogatives:
            event.addresponse(choice((
                u"I'm afraid I have no idea",
                u"Not a clue, sorry",
                u"Erk, dunno",
            )))
            return

        factoid = event.session.query(Factoid).join(Factoid.names)\
                .filter(FactoidName.name==escape_name(name)).first()
        if factoid:
            if correction:
                identities = get_identities(event)
                if not auth_responses(event, u'factoidadmin') and len(filter(lambda x: x.identity_id not in identities, factoid.values)) > 0:
                    return
                for fvalue in factoid.values:
                    event.session.delete(fvalue)
            elif not addition:
                event.addresponse(u'I already know stuff about %s', name)
                return
        else:
            factoid = Factoid()
            fname = FactoidName(unicode(name), event.identity)
            factoid.names.append(fname)
            event.session.save_or_update(factoid)
            event.session.flush()
            log.info(u"Creating factoid %s with name '%s' by %s", factoid.id, fname.name, event.identity)

        if not reply_re.match(value) and not action_re.match(value):
            value = '%s %s' % (verb, value)
        fvalue = FactoidValue(unicode(value), event.identity)
        factoid.values.append(fvalue)
        event.session.save_or_update(factoid)
        event.session.commit()
        self.last_set_factoid=factoid.names[0].name
        log.info(u"Added value '%s' to factoid %s (%s) by %s/%s (%s)",
                fvalue.value, factoid.id, factoid.names[0].name,
                event.account, event.identity, event.sender['connection'])
        event.addresponse(choice((
                u'If you say so',
                u'One learns a new thing every day',
                u"I'll remember that",
                u'Got it',
            )))
Beispiel #10
0
    def append(self, event, name, number, pattern, is_regex, suffix):
        name = strip_name(name)
        factoids = get_factoid(event.session,
                               name,
                               number,
                               pattern,
                               is_regex,
                               all=True,
                               literal=True)
        if len(factoids) == 0:
            if pattern:
                event.addresponse(
                    u"I don't know about any %(name)s matching %(pattern)s", {
                        'name': name,
                        'pattern': pattern,
                    })
            else:
                factoids = get_factoid(event.session,
                                       name,
                                       None,
                                       pattern,
                                       is_regex,
                                       all=True)
                if factoids:
                    event.addresponse(
                        u"I only know %(number)d things about %(name)s", {
                            u'number': len(factoids),
                            u'name': name,
                        })
                else:
                    event.addresponse(u"I don't know about %s", name)
        elif len(factoids) > 1 and number is None:
            event.addresponse(
                u"Pattern matches multiple factoids, please be more specific")
        else:
            factoidadmin = auth_responses(event, u'factoidadmin')
            identities = get_identities(event)
            factoid = factoids[0]

            if factoid[2].identity_id not in identities and not factoidadmin:
                return

            oldvalue = factoid[2].value
            factoid[2].value += suffix
            event.session.add(factoid[2])
            event.session.commit()

            log.info(
                u"Appended '%s' to value %s (%s) of factoid %s (%s) by %s/%s (%s)",
                suffix, factoid[2].id, oldvalue, factoid[0].id,
                factoid[0].names[0].name, event.account, event.identity,
                event.sender['connection'])
            event.addresponse(True)
Beispiel #11
0
    def handler(self, event, user, source, method, credential):

        if user.lower() == "me":
            if not event.account:
                event.addresponse(u"I don't know who you are")
                return
            if not ibid.auth.authenticate(event):
                event.complain = "notauthed"
                return
            account = event.session.query(Account).get(event.account)

        else:
            if not auth_responses(event, "admin"):
                return
            account = event.session.query(Account).filter_by(username=user).first()
            if not account:
                event.addresponse(u"I don't know who %s is", user)
                return

        if source:
            if source not in ibid.sources:
                event.addresponse(u"I am not connected to %s", source)
                return
            source = ibid.sources[source].name

        if method.lower() == "password":
            password = hash(credential)
            event.message["clean"] = event.message["clean"][: -len(credential)] + password
            event.message["raw"] = (
                event.message["raw"][: event.message["raw"].rfind(credential)]
                + password
                + event.message["raw"][event.message["raw"].rfind(credential) + len(credential) :]
            )
            credential = password

        credential = Credential(method, credential, source, account.id)
        event.session.add(credential)
        event.session.commit()
        log.info(
            u"Added %s credential %s for account %s (%s) on %s by account %s",
            method,
            credential.credential,
            account.id,
            account.username,
            source,
            event.account,
        )

        event.addresponse(True)
Beispiel #12
0
    def get(self, event, key):
        if 'password' in key.lower() and not auth_responses(event, u'config'):
            return

        config = ibid.config
        for part in key.split('.'):
            if not isinstance(config, dict) or part not in config:
                event.addresponse(u'No such option')
                return
            config = config[part]
        if isinstance(config, list):
            event.addresponse(u', '.join(config))
        elif isinstance(config, dict):
            event.addresponse(u'Keys: ' + human_join(config.keys()))
        else:
            event.addresponse(unicode(config))
Beispiel #13
0
    def list(self, event, username):
        if not username:
            if not event.account:
                event.addresponse(u"I don't know who you are")
                return
            account = event.session.query(Account).get(event.account)
        else:
            if not auth_responses(event, u"accounts"):
                return
            account = event.session.query(Account).filter_by(username=username).first()
            if not account:
                event.addresponse(u"I don't know who %s is", username)
                return

        permissions = sorted(u"%s%s" % (permission_values[perm.value], perm.name) for perm in account.permissions)
        event.addresponse(u"Permissions: %s", human_join(permissions) or u"none")
Beispiel #14
0
    def list(self, event, username):
        if not username:
            if not event.account:
                event.addresponse(u"I don't know who you are")
                return
            account = event.session.query(Account).get(event.account)
        else:
            if not auth_responses(event, u'accounts'):
                return
            account = event.session.query(Account) \
                    .filter_by(username=username).first()
            if not account:
                event.addresponse(u"I don't know who %s is", username)
                return

        permissions = sorted(u'%s%s' % (permission_values[perm.value], perm.name) for perm in account.permissions)
        event.addresponse(u'Permissions: %s', human_join(permissions) or u'none')
Beispiel #15
0
    def handler(self, event, user, source, method, credential):

        if user.lower() == 'me':
            if not event.account:
                event.addresponse(u"I don't know who you are")
                return
            if not ibid.auth.authenticate(event):
                event.complain = 'notauthed'
                return
            account = event.session.query(Account).get(event.account)

        else:
            if not auth_responses(event, 'admin'):
                return
            account = event.session.query(Account).filter_by(
                username=user).first()
            if not account:
                event.addresponse(u"I don't know who %s is", user)
                return

        if source:
            if source not in ibid.sources:
                event.addresponse(u"I am not connected to %s", source)
                return
            source = ibid.sources[source].name

        if method.lower() == 'password':
            password = hash(credential)
            event.message[
                'clean'] = event.message['clean'][:-len(credential)] + password
            event.message['raw'] = event.message['raw'][:event.message['raw'].rfind(credential)] \
                    + password + event.message['raw'][event.message['raw'].rfind(credential)+len(credential):]
            credential = password

        credential = Credential(method, credential, source, account.id)
        event.session.save_or_update(credential)
        event.session.commit()
        log.info(
            u"Added %s credential %s for account %s (%s) on %s by account %s",
            method, credential.credential, account.id, account.username,
            source, event.account)

        event.addresponse(True)
Beispiel #16
0
    def append(self, event, name, number, pattern, is_regex, suffix):
        name = strip_name(name)
        factoids = get_factoid(event.session, name, number, pattern, is_regex, all=True, literal=True)
        if len(factoids) == 0:
            if pattern:
                event.addresponse(u"I don't know about any %(name)s matching %(pattern)s", {
                    'name': name,
                    'pattern': pattern,
                })
            else:
                factoids = get_factoid(event.session, name, None, pattern, is_regex, all=True)
                if factoids:
                    event.addresponse(u"I only know %(number)d things about %(name)s", {
                        u'number': len(factoids),
                        u'name': name,
                    })
                else:
                    event.addresponse(u"I don't know about %s", name)
        elif len(factoids) > 1 and number is None:
            event.addresponse(u"Pattern matches multiple factoids, please be more specific")
        else:
            factoidadmin = auth_responses(event, u'factoidadmin')
            identities = get_identities(event)
            factoid = factoids[0]

            if factoid[2].identity_id not in identities and not factoidadmin:
                return

            oldvalue = factoid[2].value
            factoid[2].value += suffix
            event.session.add(factoid[2])
            event.session.commit()

            log.info(u"Appended '%s' to value %s (%s) of factoid %s (%s) by %s/%s (%s)",
                    suffix, factoid[2].id, oldvalue, factoid[0].id,
                    factoid[0].names[0].name, event.account, event.identity,
                    event.sender['connection'])
            event.addresponse(True)
Beispiel #17
0
    def identity(self, event, username, identity, source):
        admin = False
        identity = identity.replace(' ', '')
        reverse_attach = False

        if username is None:
            if event.account:
                account = event.session.query(Account).get(event.account)
            else:
                account = event.session.query(Account) \
                        .join('identities') \
                        .filter(Identity.identity == identity) \
                        .filter(Identity.source == source).first()

                if account:
                    reverse_attach = True
                else:
                    username = event.sender['id']

                    account = event.session.query(Account) \
                            .filter_by(username=username).first()

                    if account:
                        event.addresponse(u'I tried to create the account %s for you, but it already exists. '
                            u"Please use 'create account <name>'", username)
                        return

                    account = Account(username)
                    event.session.save_or_update(account)

                    currentidentity = event.session.query(Identity) \
                            .get(event.identity)
                    currentidentity.account_id = account.id
                    event.session.save_or_update(currentidentity)

                    identify_cache.clear()

                    event.addresponse(u"I've created the account %s for you", username)

                    event.session.commit()
                    log.info(u"Created account %s (%s) by %s/%s (%s)",
                            account.id, account.username, event.account, event.identity, event.sender['connection'])
                    log.info(u"Attached identity %s (%s on %s) to account %s (%s)",
                            currentidentity.id, currentidentity.identity, currentidentity.source, account.id, account.username)

        else:
            if not auth_responses(event, 'accounts'):
                return
            admin = True
            account = event.session.query(Account) \
                    .filter_by(username=username).first()
            if not account:
                event.addresponse(u"I don't know who %s is", username)
                return

        if reverse_attach:
            ident = event.session.query(Identity).get(event.identity)
        else:
            ident = event.session.query(Identity) \
                    .filter_by(identity=identity, source=source).first()
        if ident and ident.account:
            event.addresponse(u'This identity is already attached to account %s',
                    ident.account.username)
            return

        if source not in ibid.sources:
            event.addresponse(u'I am not connected to %s', source)
            return
        else:
            source = ibid.sources[source].name

        if not admin:
            token = ''.join([choice(chars) for i in xrange(16)])
            if reverse_attach:
                self.tokens[token] = (account.id, ident.identity, ident.source)
                response = {
                        'reply': u'Please send me this message from %s on %s: %s' % (ident.identity, ident.source, token),
                        'target': identity,
                        'source': source,
                }
                event.addresponse(True)
            else:
                self.tokens[token] = (account.id, identity, source)
                response = {'reply': u'Please send me this message from %s on %s: %s' % (identity, source, token)}
                if event.public:
                    response['target'] = event.sender['id']
                    event.addresponse(True)
            event.addresponse(response)
            log.info(u"Sent token %s to %s/%s (%s)",
                    token, event.account, event.identity, event.sender['connection'])

        else:
            if not ident:
                ident = Identity(source, identity)
            ident.account_id = account.id
            event.session.save_or_update(ident)
            event.session.commit()

            identify_cache.clear()

            event.addresponse(True)
            log.info(u"Attached identity %s (%s on %s) to account %s (%s) by %s/%s (%s)",
                    ident.id, ident.identity, ident.source, account.id, account.username,
                    event.account, event.identity, event.sender['connection'])
Beispiel #18
0
    def identity(self, event, username, identity, source):
        admin = False
        identity = identity.replace(" ", "")
        reverse_attach = False

        if username is None:
            if event.account:
                account = event.session.query(Account).get(event.account)
            else:
                account = (
                    event.session.query(Account)
                    .join("identities")
                    .filter(Identity.identity == identity)
                    .filter(Identity.source == source)
                    .first()
                )

                if account:
                    reverse_attach = True
                else:
                    username = event.sender["id"]

                    account = event.session.query(Account).filter_by(username=username).first()

                    if account:
                        event.addresponse(
                            u"I tried to create the account %s for you, but it already exists. "
                            u"Please use 'create account <name>'",
                            username,
                        )
                        return

                    account = Account(username)
                    event.session.add(account)

                    currentidentity = event.session.query(Identity).get(event.identity)
                    currentidentity.account_id = account.id
                    event.session.add(currentidentity)

                    identify_cache.clear()

                    event.addresponse(u"I've created the account %s for you", username)

                    event.session.commit()
                    log.info(
                        u"Created account %s (%s) by %s/%s (%s)",
                        account.id,
                        account.username,
                        event.account,
                        event.identity,
                        event.sender["connection"],
                    )
                    log.info(
                        u"Attached identity %s (%s on %s) to account %s (%s)",
                        currentidentity.id,
                        currentidentity.identity,
                        currentidentity.source,
                        account.id,
                        account.username,
                    )

        else:
            if not auth_responses(event, "accounts"):
                return
            admin = True
            account = event.session.query(Account).filter_by(username=username).first()
            if not account:
                event.addresponse(u"I don't know who %s is", username)
                return

        if reverse_attach:
            ident = event.session.query(Identity).get(event.identity)
        else:
            ident = event.session.query(Identity).filter_by(identity=identity, source=source).first()
        if ident and ident.account:
            event.addresponse(u"This identity is already attached to account %s", ident.account.username)
            return

        if source not in ibid.sources:
            event.addresponse(u"I am not connected to %s", source)
            return
        else:
            source = ibid.sources[source].name

        if not admin:
            token = "".join([choice(chars) for i in xrange(16)])
            if reverse_attach:
                self.tokens[token] = (account.id, ident.identity, ident.source)
                response = {
                    "reply": u"Please send me this message from %s on %s: %s" % (ident.identity, ident.source, token),
                    "target": identity,
                    "source": source,
                }
                event.addresponse(True)
            else:
                self.tokens[token] = (account.id, identity, source)
                response = {"reply": u"Please send me this message from %s on %s: %s" % (identity, source, token)}
                if event.public:
                    response["target"] = event.sender["id"]
                    event.addresponse(True)
            event.addresponse(response)
            log.info(u"Sent token %s to %s/%s (%s)", token, event.account, event.identity, event.sender["connection"])

        else:
            if not ident:
                ident = Identity(source, identity)
            ident.account_id = account.id
            event.session.add(ident)
            event.session.commit()

            identify_cache.clear()

            event.addresponse(True)
            log.info(
                u"Attached identity %s (%s on %s) to account %s (%s) by %s/%s (%s)",
                ident.id,
                ident.identity,
                ident.source,
                account.id,
                account.username,
                event.account,
                event.identity,
                event.sender["connection"],
            )
Beispiel #19
0
    def identity(self, event, username, identity, source):
        admin = False
        identity = identity.replace(' ', '')
        reverse_attach = False

        if username is None:
            if event.account:
                account = event.session.query(Account).get(event.account)
            else:
                account = event.session.query(Account) \
                        .join('identities') \
                        .filter(Identity.identity == identity) \
                        .filter(Identity.source == source).first()

                if account:
                    reverse_attach = True
                else:
                    username = event.sender['id']

                    account = event.session.query(Account) \
                            .filter_by(username=username).first()

                    if account:
                        event.addresponse(
                            u'I tried to create the account %s for you, but it already exists. '
                            u"Please use 'create account <name>'", username)
                        return

                    account = Account(username)
                    event.session.save_or_update(account)

                    currentidentity = event.session.query(Identity) \
                            .get(event.identity)
                    currentidentity.account_id = account.id
                    event.session.save_or_update(currentidentity)

                    identify_cache.clear()

                    event.addresponse(u"I've created the account %s for you",
                                      username)

                    event.session.commit()
                    log.info(u"Created account %s (%s) by %s/%s (%s)",
                             account.id, account.username, event.account,
                             event.identity, event.sender['connection'])
                    log.info(
                        u"Attached identity %s (%s on %s) to account %s (%s)",
                        currentidentity.id, currentidentity.identity,
                        currentidentity.source, account.id, account.username)

        else:
            if not auth_responses(event, 'accounts'):
                return
            admin = True
            account = event.session.query(Account) \
                    .filter_by(username=username).first()
            if not account:
                event.addresponse(u"I don't know who %s is", username)
                return

        if reverse_attach:
            ident = event.session.query(Identity).get(event.identity)
        else:
            ident = event.session.query(Identity) \
                    .filter_by(identity=identity, source=source).first()
        if ident and ident.account:
            event.addresponse(
                u'This identity is already attached to account %s',
                ident.account.username)
            return

        if source not in ibid.sources:
            event.addresponse(u'I am not connected to %s', source)
            return
        else:
            source = ibid.sources[source].name

        if not admin:
            token = ''.join([choice(chars) for i in xrange(16)])
            if reverse_attach:
                self.tokens[token] = (account.id, ident.identity, ident.source)
                response = {
                    'reply':
                    u'Please send me this message from %s on %s: %s' %
                    (ident.identity, ident.source, token),
                    'target':
                    identity,
                    'source':
                    source,
                }
                event.addresponse(True)
            else:
                self.tokens[token] = (account.id, identity, source)
                response = {
                    'reply':
                    u'Please send me this message from %s on %s: %s' %
                    (identity, source, token)
                }
                if event.public:
                    response['target'] = event.sender['id']
                    event.addresponse(True)
            event.addresponse(response)
            log.info(u"Sent token %s to %s/%s (%s)", token, event.account,
                     event.identity, event.sender['connection'])

        else:
            if not ident:
                ident = Identity(source, identity)
            ident.account_id = account.id
            event.session.save_or_update(ident)
            event.session.commit()

            identify_cache.clear()

            event.addresponse(True)
            log.info(
                u"Attached identity %s (%s on %s) to account %s (%s) by %s/%s (%s)",
                ident.id, ident.identity, ident.source, account.id,
                account.username, event.account, event.identity,
                event.sender['connection'])
Beispiel #20
0
    def modify(self, event, name, number, pattern, is_regex, operation, sep):
        factoids = get_factoid(event.session, name, number, pattern, is_regex, all=True)
        if len(factoids) == 0:
            if pattern:
                event.addresponse(u"I don't know about any %(name)s matching %(pattern)s", {
                    'name': name,
                    'pattern': pattern,
                })
            else:
                event.addresponse(u"I don't know about %s", name)
        elif len(factoids) > 1:
            event.addresponse(u"Pattern matches multiple factoids, please be more specific")
        else:
            factoidadmin = auth_responses(event, u'factoidadmin')
            identities = get_identities(event)
            factoid = factoids[0]

            if factoid[2].identity_id not in identities and not factoidadmin:
                return

            # Not very pythonistic, but escaping is a nightmare.
            separator = sep
            parts = [[]]
            pos = 0
            while pos < len(operation):
                char = operation[pos]
                if char == separator:
                    parts.append([])
                elif char == u"\\":
                    if pos < len(operation) - 1:
                        if operation[pos+1] == u"\\":
                            parts[-1].append(u"\\")
                            pos += 1
                        elif operation[pos+1] == separator:
                            parts[-1].append(separator)
                            pos += 1
                        else:
                            parts[-1].append(u"\\")
                    else:
                        parts[-1].append(u"\\")
                else:
                    parts[-1].append(char)
                pos += 1

            parts = [u"".join(x) for x in parts]

            if len(parts) != 4:
                event.addresponse(u"That operation makes no sense. Try something like s/foo/bar/")
                return

            oldvalue = factoid[2].value
            op, search, replace, flags = parts
            flags = flags.lower()
            if op == "s":
                if "r" not in flags:
                    plain_search = search
                    search = re.escape(search)
                    replace = replace.replace('\\', '\\\\')
                if "i" in flags:
                    search += "(?i)"
                try:
                    if "r" not in flags and not re.search(search, oldvalue):
                        event.addresponse(u"I couldn't find '%(terms)s' in "
                                          u"'%(oldvalue)s'. If that was a "
                                          u"proper regular expression, append "
                                          u"the 'r' flag", {
                                                'terms': plain_search,
                                                'oldvalue': oldvalue,
                                            })
                        return

                    factoid[2].value = re.sub(search, replace, oldvalue, int("g" not in flags))
                except:
                    event.addresponse(u"That operation makes no sense. Try something like s/foo/bar/")
                    return

            elif op == "y":
                if len(search) != len(replace):
                    event.addresponse(u"That operation makes no sense. The source and destination must be the same length")
                    return
                try:
                    table = dict((ord(x), ord(y)) for x, y in zip(search, replace))
                    factoid[2].value = oldvalue.translate(table)

                except:
                    event.addresponse(u"That operation makes no sense. Try something like y/abcdef/ABCDEF/")
                    return

            event.session.save_or_update(factoid[2])
            event.session.commit()

            log.info(u"Applying '%s' to value %s of factoid %s (%s) by %s/%s (%s)",
                    operation, factoid[2].id, factoid[0].id, oldvalue, event.account, event.identity, event.sender['connection'])

            event.addresponse(True)
Beispiel #21
0
    def forget(self, event, name, number, pattern, is_regex):
        factoids = get_factoid(event.session, name, number, pattern, is_regex, all=True, literal=True)
        if factoids:
            factoidadmin = auth_responses(event, u'factoidadmin')
            identities = get_identities(event)
            factoid = event.session.query(Factoid).get(factoids[0][0].id)

            if len(factoids) > 1 and pattern is not None:
                event.addresponse(u'Pattern matches multiple factoids, please be more specific')
                return

            if number or pattern:
                if factoids[0][2].identity_id not in identities and not factoidadmin:
                    return

                if event.session.query(FactoidValue).filter_by(factoid_id=factoid.id).count() == 1:
                    if len(filter(lambda x: x.identity_id not in identities, factoid.names)) > 0 and not factoidadmin:
                        return
                    id = factoid.id
                    event.session.delete(factoid)
                    event.session.commit()
                    log.info(u"Deleted factoid %s (%s) by %s/%s (%s)",
                            id, name, event.account, event.identity, event.sender['connection'])
                else:
                    id = factoids[0][2].id
                    event.session.delete(factoids[0][2])
                    event.session.commit()
                    log.info(u"Deleted value %s (%s) of factoid %s (%s) by %s/%s (%s)",
                            id, factoids[0][2].value, factoid.id, name,
                            event.account, event.identity, event.sender['connection'])

            else:
                if factoids[0][1].identity_id not in identities and not factoidadmin:
                    return

                if event.session.query(FactoidName).filter_by(factoid_id=factoid.id).count() == 1:
                    if len(filter(lambda x: x.identity_id not in identities, factoid.values)) > 0 and not factoidadmin:
                        return
                    id = factoid.id
                    event.session.delete(factoid)
                    event.session.commit()
                    log.info(u"Deleted factoid %s (%s) by %s/%s (%s)",
                            id, name, event.account, event.identity,
                            event.sender['connection'])
                else:
                    id = factoids[0][1].id
                    event.session.delete(factoids[0][1])
                    event.session.commit()
                    log.info(u"Deleted name %s (%s) of factoid %s (%s) by %s/%s (%s)",
                            id, factoids[0][1].name, factoid.id, factoids[0][0].names[0].name,
                            event.account, event.identity, event.sender['connection'])

            event.addresponse(True)
        else:
            factoids = get_factoid(event.session, name, None, pattern, is_regex, all=True, literal=True)
            if factoids:
                event.addresponse(u"I only know %(number)d things about %(name)s", {
                    u'number': len(factoids),
                    u'name': name,
                })
            else:
                event.addresponse(u"I didn't know about %s anyway", name)
Beispiel #22
0
    def modify(self, event, name, number, pattern, is_regex, operation, sep):
        factoids = get_factoid(event.session,
                               name,
                               number,
                               pattern,
                               is_regex,
                               all=True)
        if len(factoids) == 0:
            if pattern:
                event.addresponse(
                    u"I don't know about any %(name)s matching %(pattern)s", {
                        'name': name,
                        'pattern': pattern,
                    })
            else:
                event.addresponse(u"I don't know about %s", name)
        elif len(factoids) > 1:
            event.addresponse(
                u"Pattern matches multiple factoids, please be more specific")
        else:
            factoidadmin = auth_responses(event, u'factoidadmin')
            identities = get_identities(event)
            factoid = factoids[0]

            if factoid[2].identity_id not in identities and not factoidadmin:
                return

            # Not very pythonistic, but escaping is a nightmare.
            separator = sep
            parts = [[]]
            pos = 0
            while pos < len(operation):
                char = operation[pos]
                if char == separator:
                    parts.append([])
                elif char == u"\\":
                    if pos < len(operation) - 1:
                        if operation[pos + 1] == u"\\":
                            parts[-1].append(u"\\")
                            pos += 1
                        elif operation[pos + 1] == separator:
                            parts[-1].append(separator)
                            pos += 1
                        else:
                            parts[-1].append(u"\\")
                    else:
                        parts[-1].append(u"\\")
                else:
                    parts[-1].append(char)
                pos += 1

            parts = [u"".join(x) for x in parts]

            if len(parts) != 4:
                event.addresponse(
                    u"That operation makes no sense. Try something like s/foo/bar/"
                )
                return

            oldvalue = factoid[2].value
            op, search, replace, flags = parts
            flags = flags.lower()
            if op == "s":
                if "r" not in flags:
                    plain_search = search
                    search = re.escape(search)
                    replace = replace.replace('\\', '\\\\')
                if "i" in flags:
                    search += "(?i)"
                try:
                    if "r" not in flags and not re.search(search, oldvalue):
                        event.addresponse(
                            u"I couldn't find '%(terms)s' in "
                            u"'%(oldvalue)s'. If that was a "
                            u"proper regular expression, append "
                            u"the 'r' flag", {
                                'terms': plain_search,
                                'oldvalue': oldvalue,
                            })
                        return

                    factoid[2].value = re.sub(search, replace, oldvalue,
                                              int("g" not in flags))
                except:
                    event.addresponse(
                        u"That operation makes no sense. Try something like s/foo/bar/"
                    )
                    return

            elif op == "y":
                if len(search) != len(replace):
                    event.addresponse(
                        u"That operation makes no sense. The source and destination must be the same length"
                    )
                    return
                try:
                    table = dict(
                        (ord(x), ord(y)) for x, y in zip(search, replace))
                    factoid[2].value = oldvalue.translate(table)

                except:
                    event.addresponse(
                        u"That operation makes no sense. Try something like y/abcdef/ABCDEF/"
                    )
                    return

            event.session.add(factoid[2])
            event.session.commit()

            log.info(
                u"Applying '%s' to value %s (%s) of factoid %s (%s) by %s/%s (%s)",
                operation, factoid[2].id, oldvalue, factoid[0].id,
                factoid[0].names[0].name, event.account, event.identity,
                event.sender['connection'])

            event.addresponse(True)
Beispiel #23
0
    def forget(self, event, name, number, pattern, is_regex):
        factoids = get_factoid(event.session,
                               name,
                               number,
                               pattern,
                               is_regex,
                               all=True,
                               literal=True)
        if factoids:
            factoidadmin = auth_responses(event, u'factoidadmin')
            identities = get_identities(event)
            factoid = event.session.query(Factoid).get(factoids[0][0].id)

            if len(factoids) > 1 and pattern is not None:
                event.addresponse(
                    u'Pattern matches multiple factoids, please be more specific'
                )
                return

            if number or pattern:
                if factoids[0][
                        2].identity_id not in identities and not factoidadmin:
                    return

                if event.session.query(FactoidValue).filter_by(
                        factoid_id=factoid.id).count() == 1:
                    if len(
                            filter(lambda x: x.identity_id not in identities,
                                   factoid.names)) > 0 and not factoidadmin:
                        return
                    id = factoid.id
                    event.session.delete(factoid)
                    event.session.commit()
                    log.info(u"Deleted factoid %s (%s) by %s/%s (%s)", id,
                             name, event.account, event.identity,
                             event.sender['connection'])
                else:
                    id = factoids[0][2].id
                    event.session.delete(factoids[0][2])
                    event.session.commit()
                    log.info(
                        u"Deleted value %s (%s) of factoid %s (%s) by %s/%s (%s)",
                        id, factoids[0][2].value, factoid.id, name,
                        event.account, event.identity,
                        event.sender['connection'])

            else:
                if factoids[0][
                        1].identity_id not in identities and not factoidadmin:
                    return

                if event.session.query(FactoidName).filter_by(
                        factoid_id=factoid.id).count() == 1:
                    if len(
                            filter(lambda x: x.identity_id not in identities,
                                   factoid.values)) > 0 and not factoidadmin:
                        return
                    id = factoid.id
                    event.session.delete(factoid)
                    event.session.commit()
                    log.info(u"Deleted factoid %s (%s) by %s/%s (%s)", id,
                             name, event.account, event.identity,
                             event.sender['connection'])
                else:
                    id = factoids[0][1].id
                    event.session.delete(factoids[0][1])
                    event.session.commit()
                    log.info(
                        u"Deleted name %s (%s) of factoid %s (%s) by %s/%s (%s)",
                        id, factoids[0][1].name, factoid.id,
                        factoids[0][0].names[0].name, event.account,
                        event.identity, event.sender['connection'])

            event.addresponse(True)
        else:
            factoids = get_factoid(event.session,
                                   name,
                                   None,
                                   pattern,
                                   is_regex,
                                   all=True,
                                   literal=True)
            if factoids:
                event.addresponse(
                    u"I only know %(number)d things about %(name)s", {
                        u'number': len(factoids),
                        u'name': name,
                    })
            else:
                event.addresponse(u"I didn't know about %s anyway", name)