Esempio n. 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...")
Esempio n. 2
0
    def run(self):
        self.running = True

        while self.running:
            try:
                parts = input("").split(" ")

                cmd = parts[0].lower()

                if cmd == "quit":
                    self.botserver.quit()
                    break

                # Example command: Useless, but just an example, for what
                # console handler could do
                elif cmd == "createchannel":
                    if len(parts) < 2:
                        print("Usage: createchannel <channel>")
                    else:
                        self.botserver.slack_wrapper.create_channel(parts[1])
                elif cmd == "set":
                    if len(parts) < 3:
                        self.show_set_usage()
                    else:
                        self.update_config(parts[1], parts[2])
            except Exception:
                log.exception(
                    "An error has occured while processing a console command")
Esempio n. 3
0
    def push(self, repo_user, repo_pass, repo_remote, repo_branch):
        """Push the current commit to git."""
        try:
            if repo_pass:
                porcelain.push(
                    self.repo,
                    "https://{}:{}@{}".format(repo_user, repo_pass,
                                              repo_remote),
                    bytes(repo_branch, "utf-8"))
            else:
                porcelain.push(self.repo, "git@{}".format(repo_remote),
                               bytes(repo_branch, "utf-8"))

        except dulwich.errors.GitProtocolError:
            raise InvalidCommand(
                "Upload file failed: GitProtocolError - Check your username and password in the git configuration..."
            )
        except KeyError:
            raise InvalidCommand(
                "Upload file failed: KeyError - Check your git configuration for missing keys..."
            )
        except TypeError:
            raise InvalidCommand(
                "Upload file failed: TypeError - Did you forget to create a git configuration?"
            )
        except Exception:
            log.exception("GitHandler::push()")
            raise InvalidCommand(
                "Upload file failed: Unknown - Please check your log files...")
Esempio n. 4
0
 def commit(self, commit_message):
     """Commit the current changeset."""
     try:
         porcelain.commit(self.repo, bytes(commit_message, "utf-8"))
     except Exception:
         # Anonymizing exceptions
         log.exception("GitHandler::commit()")
         raise InvalidCommand("Comitting file failed: Please check your log files...")
Esempio n. 5
0
    def __init__(self, repo_path):
        try:
            self.repo_path = repo_path

            self.repo = porcelain.open_repo(repo_path)
        except Exception:
            log.exception("GitHandler::__init__()")
            raise InvalidCommand("Opening repo failed: Please check your log")
Esempio n. 6
0
    def execute(cls, slack_wrapper, args, channel_id, user_id, user_is_admin):
        """Execute the Version command."""
        try:
            message = GitHandler(".").get_version()

            slack_wrapper.post_message(channel_id, message)
        except:
            log.exception("BotHandler::VersionCommand")
            raise InvalidCommand("Sorry, couldn't retrieve the git information for the bot...")
Esempio n. 7
0
    def add_file(self, data, filename):
        """Add a file to the commit."""
        try:
            full_filename = os.path.join(self.repo_path, filename)

            with open(full_filename, "w") as f:
                f.write(data)

            porcelain.add(self.repo, full_filename)
        except Exception:
            # Anonymizing exceptions
            log.exception("GitHandler::add_file()")
            raise InvalidCommand("Adding file failed: Please check your log files...")
Esempio n. 8
0
    def execute(cls, slack_wrapper, args, timestamp, channel_id, user_id, user_is_admin):
        current_members = slack_wrapper.get_channel_members(channel_id)
        # strip uid formatting
        invited_users = [user.strip("<>@") for user in args]
        # remove already present members
        invited_users = [user for user in invited_users if user not in current_members]
        failed_users = []
        for member in invited_users:
            if not slack_wrapper.invite_user(member, channel_id)["ok"]:
                failed_users.append(member)

        if failed_users:
            log.exception("BotHandler::InviteCommand")
            raise InvalidCommand("Sorry, couldn't invite the following members to the channel: " + ' '.join(failed_users))
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")
Esempio n. 10
0
def post_ctf_data(ctf, title):
    """Create a post and a statistic file and upload it to the configured SolveTracker repository."""
    if not ST_GIT_SUPPORT:
        raise Exception(
            "Sorry, but the SolveTracker support isn't configured...")

    try:
        now = datetime.datetime.now()

        post_data = resolve_ctf_template(
            ctf, title, "./templates/post_ctf_template",
            "./templates/post_challenge_template")
        post_filename = "_posts/{}-{}-{}-{}.md".format(now.year, now.month,
                                                       now.day, ctf.name)

        stat_data = resolve_stats_template(ctf)
        stat_filename = "_stats/{}.json".format(ctf.name)

        git = GitHandler(ST_GIT_CONFIG.get("git_repopath"))

        git.add_file(post_data, post_filename)
        git.add_file(stat_data, stat_filename)

        git.commit("Solve post from {}".format(ctf.name))

        git.push(ST_GIT_CONFIG.get("git_repouser"),
                 ST_GIT_CONFIG.get("git_repopass"),
                 ST_GIT_CONFIG.get("git_remoteuri"),
                 ST_GIT_CONFIG.get("git_branch"))

        return ST_GIT_CONFIG.get("git_baseurl")

    except InvalidCommand as invalid_cmd:
        # Just pass invalid commands on
        raise invalid_cmd
    except Exception:
        log.exception("SolvePostHelper")
        raise InvalidCommand(
            "Something with your configuration files doesn't seem to be correct. Please check your logfiles..."
        )
Esempio n. 11
0
    def run(self):
        log.info("Starting server thread...")

        self.running = True

        while self.running:
            try:
                self.load_config()
                self.slack_wrapper = SlackWrapper(
                    self.get_config_option("api_key"))

                if self.slack_wrapper.connected:
                    log.info("Connection successful...")
                    self.init_bot_data()

                    # Main loop
                    log.info("Bot is running...")
                    while self.running:
                        message = self.slack_wrapper.read()
                        if message:
                            self.handle_message(message)

                        time.sleep(self.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)
            except:
                log.exception("Unhandled error. Try reconnect...")
                time.sleep(5)

        log.info("Shutdown complete...")
Esempio n. 12
0
def process_command(slack_wrapper,
                    message,
                    args,
                    timestamp,
                    channel_id,
                    user_id,
                    admin_override=False):

    try:
        handler_name = args[0].lower()
        processed = False
        usage_msg = ""

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

        if admin_override:
            user_is_admin = True

        # Call a specific handler with this command
        handler = handlers.get(handler_name)

        if handler:
            # Setup usage message
            if len(args) < 2 or args[1] == "help":
                usage_msg += handler.get_usage(user_is_admin)
                processed = True

            else:  # Send command to specified handler
                command = args[1].lower()
                if handler.can_handle(command, user_is_admin):
                    handler.process(slack_wrapper, command, args[2:],
                                    timestamp, channel_id, user_id,
                                    user_is_admin)
                    processed = True

        else:  # Pass the command to every available handler
            command = args[0].lower()

            for handler_name, handler in handlers.items():
                if command == "help":  # Setup usage message
                    usage_msg += "{}\n".format(
                        handler.get_usage(user_is_admin))
                    processed = True

                elif handler.can_handle(
                        command, user_is_admin):  # Send command to handler
                    handler.process(slack_wrapper, command, args[1:],
                                    timestamp, channel_id, user_id,
                                    user_is_admin)
                    processed = True

        if not processed:  # Send error message
            message = "Unknown handler or command : `{}`".format(message)
            slack_wrapper.post_message(channel_id, message, timestamp)

        if usage_msg:  # Send usage message
            send_help_as_dm = botserver.get_config_option(
                "send_help_as_dm") == "1"
            target_id = user_id if send_help_as_dm else channel_id
            slack_wrapper.post_message(target_id, usage_msg)

    except InvalidCommand as e:
        slack_wrapper.post_message(channel_id, e, timestamp)

    except Exception:
        log.exception("An error has occured while processing a command")