<reponame>yanlinw/securitybot
'''
File for securitybot commands.

Each command function takes a user and arguments as its arguments.
It also has `bot`, a reference to the bot that called it.
They return True upon success and False upon failure, or just None
if the command doesn't have success/failure messages.
'''
import re
import logging
from datetime import datetime, timedelta
import json
import securitybot.ignored_alerts as ignored_alerts
from securitybot.util import create_new_alert
from securitybot.analytics.analytics import list_insightlet_message, get_insightlet_id, DASHBOARD_URL

def hi(bot, user, args):
    '''Says hello to a user.'''
    bot.chat.message_user(user, bot.messages['hi'].format(user.get_name()))

def help(bot, user, args):
    '''Prints help for each command.'''
    msg = '{0}\n\n'.format(bot.messages['help_header'])
    for name, info in sorted(bot.commands.items()):
        if not info['hidden'] or '-a' in args:
            msg += '`{0}`: {1}\n'.format(name, info['info'])
            if info['usage']:
                usage_str = '\n'.join(['> \t' + s for s in info['usage']])
                msg += '> {0}:\n{1}\n'.format(bot.messages['help_usage'], usage_str)
    msg += bot.messages['help_footer']
    bot.chat.message_user(user, msg)

def add_to_blacklist(bot, user, args):
    '''Adds a user to the blacklist.'''
    name = user['name']
    if not bot.blacklist.is_present(name):
        bot.blacklist.add(name)
        return True
    return False

def remove_from_blacklist(bot, user, args):
    '''Removes a user from the blacklist.'''
    name = user['name']
    if bot.blacklist.is_present(name):
        bot.blacklist.remove(name)
        return True
    return False

def positive_response(bot, user, args):
    '''Registers a postive response from a user.'''
    user.positive_response(' '.join(args))

def negative_response(bot, user, args):
    '''Registers a negative response from a user.'''
    user.negative_response(' '.join(args))

TIME_REGEX = re.compile(r'([0-9]+h)?([0-9]+m)?', flags=re.IGNORECASE)
OUTATIME = timedelta()
TIME_LIMIT = timedelta(hours=4)

def ignore(bot, user, args):
    '''Ignores a specific alert for a user for some period of time.'''
    if len(args) != 2:
        return False

    which, time = args

    # Find correct task in user object
    task = None
    if which == 'last' and user.tasks:
        task = user.tasks[-1]
    elif which == 'current' and user.pending_task:
        task = user.pending_task
    if task is None:
        return False

    # Parse given time using above regex
    match = TIME_REGEX.match(time)
    if not (match or match.group(0)):
        return False
    # Parse time returned by regex, snipping off the trailing letter
    hours = int(match.group(1)[:-1]) if match.group(1) else 0
    minutes = int(match.group(2)[:-1]) if match.group(2) else 0
    # Build and cap time if needed
    ignoretime = timedelta(hours=hours, minutes=minutes)
    if ignoretime > TIME_LIMIT:
        bot.chat.message_user(user, bot.messages['ignore_time'])
        ignoretime = TIME_LIMIT
    elif ignoretime <= OUTATIME:
        bot.chat.message_user(user, bot.messages['ignore_no_time'])
        return False

    ignored_alerts.ignore_task(user['name'], task.title, 'ignored', ignoretime)
    return True

def test(bot, user, args):
    '''Creates a new test alert in Maniphest for a user.'''
    create_new_alert('testing_alert', user['name'], 'Testing alert', 'Testing Securitybot', user=user['name'],
                     alert_time=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), location='Santa Clara',
                     target='127.0.0.1', source='127.0.0.1', risk='High')

    return True

def insightlet(bot, user, args):
    if len(args)<1:
        # list the insights
        msg = list_insightlet_message()
        msg += "Please find the insightlet id you want to run\n"
        msg += "```insightlet id```"
        bot.chat.message_user(user, msg)
        return True
    if len(args) == 1:
        name, insightlet_url = get_insightlet_id(args[0])
        logging.info ("insight_url = " + insightlet_url)
        msg_att = bot.messages['insightlet'].format(title=name, url=DASHBOARD_URL, insightlet=insightlet_url)
        msg_att_json = json.loads(msg_att)
        bot.chat.message_user(user, '', msg_att_json)
        return True

'''
File for securitybot commands.

Each command function takes a user and arguments as its arguments.
It also has `bot`, a reference to the bot that called it.
They return True upon success and False upon failure, or just None
if the command doesn't have success/failure messages.
'''
import re
import logging
from datetime import datetime, timedelta
import json
import securitybot.ignored_alerts as ignored_alerts
from securitybot.util import create_new_alert
from securitybot.analytics.analytics import list_insightlet_message, get_insightlet_id, DASHBOARD_URL

def hi(bot, user, args):
    '''Says hello to a user.'''
    bot.chat.message_user(user, bot.messages['hi'].format(user.get_name()))

def help(bot, user, args):
    '''Prints help for each command.'''
    msg = '{0}\n\n'.format(bot.messages['help_header'])
    for name, info in sorted(bot.commands.items()):
        if not info['hidden'] or '-a' in args:
            msg += '`{0}`: {1}\n'.format(name, info['info'])
            if info['usage']:
                usage_str = '\n'.join(['> \t' + s for s in info['usage']])
                msg += '> {0}:\n{1}\n'.format(bot.messages['help_usage'], usage_str)
    msg += bot.messages['help_footer']
    bot.chat.message_user(user, msg)

def add_to_blacklist(bot, user, args):
    '''Adds a user to the blacklist.'''
    name = user['name']
    if not bot.blacklist.is_present(name):
        bot.blacklist.add(name)
        return True
    return False

def remove_from_blacklist(bot, user, args):
    '''Removes a user from the blacklist.'''
    name = user['name']
    if bot.blacklist.is_present(name):
        bot.blacklist.remove(name)
        return True
    return False

def positive_response(bot, user, args):
    '''Registers a postive response from a user.'''
    user.positive_response(' '.join(args))

def negative_response(bot, user, args):
    '''Registers a negative response from a user.'''
    user.negative_response(' '.join(args))

TIME_REGEX = re.compile(r'([0-9]+h)?([0-9]+m)?', flags=re.IGNORECASE)
OUTATIME = timedelta()
TIME_LIMIT = timedelta(hours=4)

def ignore(bot, user, args):
    '''Ignores a specific alert for a user for some period of time.'''
    if len(args) != 2:
        return False

    which, time = args

    # Find correct task in user object
    task = None
    if which == 'last' and user.tasks:
        task = user.tasks[-1]
    elif which == 'current' and user.pending_task:
        task = user.pending_task
    if task is None:
        return False

    # Parse given time using above regex
    match = TIME_REGEX.match(time)
    if not (match or match.group(0)):
        return False
    # Parse time returned by regex, snipping off the trailing letter
    hours = int(match.group(1)[:-1]) if match.group(1) else 0
    minutes = int(match.group(2)[:-1]) if match.group(2) else 0
    # Build and cap time if needed
    ignoretime = timedelta(hours=hours, minutes=minutes)
    if ignoretime > TIME_LIMIT:
        bot.chat.message_user(user, bot.messages['ignore_time'])
        ignoretime = TIME_LIMIT
    elif ignoretime <= OUTATIME:
        bot.chat.message_user(user, bot.messages['ignore_no_time'])
        return False

    ignored_alerts.ignore_task(user['name'], task.title, 'ignored', ignoretime)
    return True

def test(bot, user, args):
    '''Creates a new test alert in Maniphest for a user.'''
    create_new_alert('testing_alert', user['name'], 'Testing alert', 'Testing Securitybot', user=user['name'],
                     alert_time=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), location='Santa Clara',
                     target='127.0.0.1', source='127.0.0.1', risk='High')

    return True

def insightlet(bot, user, args):
    if len(args)<1:
        # list the insights
        msg = list_insightlet_message()
        msg += "Please find the insightlet id you want to run\n"
        msg += "```insightlet id```"
        bot.chat.message_user(user, msg)
        return True
    if len(args) == 1:
        name, insightlet_url = get_insightlet_id(args[0])
        logging.info ("insight_url = " + insightlet_url)
        msg_att = bot.messages['insightlet'].format(title=name, url=DASHBOARD_URL, insightlet=insightlet_url)
        msg_att_json = json.loads(msg_att)
        bot.chat.message_user(user, '', msg_att_json)
        return True
File for securitybot commands.  Each command function takes a user and arguments as its arguments. It also has `bot`, a reference to the bot that called it. They return True upon success and False upon failure, or just None if the command doesn't have success/failure messages. Says hello to a user. Prints help for each command. Adds a user to the blacklist. Removes a user from the blacklist. Registers a postive response from a user. Registers a negative response from a user. Ignores a specific alert for a user for some period of time. # Find correct task in user object # Parse given time using above regex # Parse time returned by regex, snipping off the trailing letter # Build and cap time if needed Creates a new test alert in Maniphest for a user. # list the insights