Пример #1
0
    def run(self):
        log.info("Starting server thread...")

        self.running = True
        self.load_config()
        self.slack_wrapper = SlackWrapper(self.get_config_option("api_key"))
        self.start_services()

        while self.running:
            try:
                if self.slack_wrapper.connected:
                    log.info("Connection successful...")
                    self.load_bot_data()
                    read_websocket_delay = 1  # 1 second delay between reading from firehose

                    # Might even pass the bot server for handlers?
                    log.info("Initializing handlers...")
                    handler_factory.initialize(self.slack_wrapper, self)

                    # Main loop
                    log.info("Bot is running...")
                    while self.running:
                        message = self.slack_wrapper.read()
                        if message:
                            reaction, channel, ts, reaction_user = self.parse_slack_reaction(
                                message)

                            if reaction:
                                log.debug("Received reaction : {} ({})".format(
                                    reaction, channel))
                                handler_factory.process_reaction(
                                    self.slack_wrapper, reaction, ts, channel,
                                    reaction_user)

                            command, channel, user = self.parse_slack_message(
                                message)

                            if command:
                                log.debug(
                                    "Received bot command : {} ({})".format(
                                        command, channel))
                                handler_factory.process(
                                    self.slack_wrapper, command, channel, user)

                            time.sleep(read_websocket_delay)
                else:
                    log.error(
                        "Connection failed. Invalid slack token or bot id?")
                    self.running = False
            except websocket._exceptions.WebSocketConnectionClosedException:
                log.exception("Web socket error. Executing reconnect...")
            except SlackConnectionError:
                # Try to reconnect if slackclient auto_reconnect didn't work out. Keep an eye on the logfiles,
                # and remove the superfluous exception handling if auto_reconnect works.
                log.exception(
                    "Slack connection error. Trying manual reconnect in 5 seconds..."
                )
                time.sleep(5)
        self.stop_services()
        log.info("Shutdown complete...")
    def execute(cls, slack_wrapper, args, timestamp, channel_id, user_id,
                user_is_admin):
        old_name = args[0].lower()
        new_name = args[1].lower()

        # Validate that the user is in a CTF channel
        ctf = get_ctf_by_channel_id(ChallengeHandler.DB, channel_id)

        if not ctf:
            raise InvalidCommand(
                "Rename challenge failed: You are not in a CTF channel.")

        if len(new_name) > (MAX_CHANNEL_NAME_LENGTH - len(ctf.name) - 1):
            raise InvalidCommand(
                "Rename challenge failed: Challenge name must be <= {} characters."
                .format(MAX_CHANNEL_NAME_LENGTH - len(ctf.name) - 1))

        # Check for invalid characters
        if not is_valid_name(new_name):
            raise InvalidCommand(
                "Command failed: Invalid characters for challenge name found.")

        old_channel_name = "{}-{}".format(ctf.name, old_name)
        new_channel_name = "{}-{}".format(ctf.name, new_name)

        # Get the channel id for the channel to rename
        challenge = get_challenge_by_name(ChallengeHandler.DB, old_name,
                                          ctf.channel_id)

        if not challenge:
            raise InvalidCommand(
                "Rename challenge failed: Challenge '{}' not found.".format(
                    old_name))

        log.debug("Renaming channel %s to %s", channel_id, new_name)
        response = slack_wrapper.rename_channel(challenge.channel_id,
                                                new_channel_name,
                                                is_private=True)

        if not response['ok']:
            raise InvalidCommand(
                "\"{}\" channel rename failed:\nError: {}".format(
                    old_channel_name, response['error']))

        # Update channel purpose
        slack_wrapper.update_channel_purpose_name(challenge.channel_id,
                                                  new_name,
                                                  is_private=True)

        # Update database
        update_challenge_name(ChallengeHandler.DB, challenge.channel_id,
                              new_name)

        text = "Challenge `{}` renamed to `{}` (#{})".format(
            old_name, new_name, new_channel_name)
        slack_wrapper.post_message(channel_id, text)
Пример #3
0
 def __init__(self):
     log.debug("Parse config file and initialize threading...")
     threading.Thread.__init__(self)
     self.running = False
     self.config = {}
     self.bot_name = ""
     self.bot_id = ""
     self.bot_at = ""
     self.slack_wrapper = None
     self.read_websocket_delay = 1
Пример #4
0
 def load_bot_data(self):
     """
     Fetches the bot user information such as
     bot_name, bot_id and bot_at.
     """
     log.debug("Resolving bot user in slack")
     self.bot_name = self.slack_wrapper.username
     self.bot_id = self.slack_wrapper.user_id
     self.bot_at = "<@{}>".format(self.bot_id)
     log.debug("Found bot user {} ({})".format(self.bot_name, self.bot_id))
     self.running = True
Пример #5
0
    def init_bot_data(self):
        """
        Fetches the bot user information such as
        bot_name, bot_id and bot_at.
        """
        log.debug("Resolving bot user in slack")
        self.bot_name = self.slack_wrapper.username
        self.bot_id = self.slack_wrapper.user_id
        self.bot_at = "<@{}>".format(self.bot_id)
        log.debug("Found bot user %s (%s)", self.bot_name, self.bot_id)
        self.running = True

        # Might even pass the bot server for handlers?
        log.info("Initializing handlers...")
        handler_factory.initialize(self.slack_wrapper, self)
Пример #6
0
    def handle_message(self, message):
        reaction, channel, time_stamp, reaction_user = self.parse_slack_reaction(
            message)

        if reaction and not self.bot_id == reaction_user:
            log.debug("Received reaction : %s (%s)", reaction, channel)
            handler_factory.process_reaction(self.slack_wrapper, reaction,
                                             time_stamp, channel,
                                             reaction_user)

        command, channel, time_stamp, user = self.parse_slack_message(message)

        if command and not self.bot_id == user:
            log.debug("Received bot command : %s (%s)", command, channel)
            handler_factory.process(self.slack_wrapper, self, command,
                                    time_stamp, channel, user)
Пример #7
0
def process_reaction(slack_wrapper, reaction, timestamp, channel_id, user_id):
    try:
        log.debug("Processing reaction: %s from %s (%s)", reaction, channel_id,
                  timestamp)

        admin_users = botserver.get_config_option("admin_users")
        user_is_admin = admin_users and user_id in admin_users

        for handler_name, handler in handlers.items():
            if handler.can_handle_reaction(reaction):
                handler.process_reaction(slack_wrapper, reaction, channel_id,
                                         timestamp, user_id, user_is_admin)
    except InvalidCommand as e:
        slack_wrapper.post_message(channel_id, e, timestamp)

    except Exception:
        log.exception("An error has occured while processing a command")
Пример #8
0
def process(slack_wrapper, botserver, message, timestamp, channel_id, user_id):
    log.debug("Processing message: %s from %s (%s)", message, channel_id,
              user_id)

    try:  # Parse command and check for malformed input
        command_line = unidecode(message)

        lexer = shlex.shlex(command_line, posix=True)
        lexer.quotes = '"'
        lexer.whitespace_split = True

        args = list(lexer)
    except:
        message = "Command failed : Malformed input."
        slack_wrapper.post_message(channel_id, message, timestamp)
        return

    process_command(slack_wrapper, message, args, timestamp, channel_id,
                    user_id)