~robin_jadoul/organizers-bot

3a593f820e101867fc32d2c3fe79e6c313b21cf3 — LucidBrot 2 years ago f015ce5
Hopefully, this fixes the issue that some challenges were not found with /solved and /assign.

We now use the pinned message to retrieve the challenge id instead of filtering by name and hoping the channel name matches the ctfnote task name.
2 files changed, 22 insertions(+), 5 deletions(-)

M organizers_bot/bot.py
M organizers_bot/ctfnote.py
M organizers_bot/bot.py => organizers_bot/bot.py +1 -1
@@ 117,7 117,7 @@ def setup():
        if not ctx.channel.name.startswith("✓"):
            await ctx.channel.edit(name=f"✓-{ctx.channel.name}", position=999)

        ctfnote_res = await ctfnote.update_flag(ctx, flag, solved_prefix="✓-")
        ctfnote_res = await ctfnote.update_flag(ctx, flag)

        if flag is not None:
            msg = await ctx.send(f"The flag: `{flag}`")

M organizers_bot/ctfnote.py => organizers_bot/ctfnote.py +21 -4
@@ 151,6 151,11 @@ class CTF:
        return next(filter(lambda x: x.id == id, self.tasks))

    async def getTaskByName(self, name: str, solved_prefix: str ="✓-"):
        """
            Problematic when there are spaces in the task title (but not the channel name).
            Problematic if two tasks have the same name.
            Prefer using getTaskByChannelPin where possible.
        """
        await self._fullupdate() # we always update bc we assume players have been creating new tasks
        # If the task was marked as solved, we need to ignore the prefix
        if name.startswith(solved_prefix):


@@ 158,6 163,17 @@ class CTF:

        return next(filter(lambda x: x.title == name, self.tasks), None)

    async def getTaskByChannelPin(self, ctx: discord_slash.SlashContext):
        """
            Get task id from pinned message in current channel,
            find it in the ctfnote response, return it.
        """
        botdb = (await extract_botdb(await get_pinned_ctfnote_message(ctx)))
        stored_challenge_id = (botdb or dict()).get('chalid', None)
        await self._fullupdate()
        return next(filter(lambda x: x.id == stored_challenge_id, self.tasks), None)


    async def createTask(self, name, category, description="", flag="", solved_prefix: str = "✓-"):
        """
        Create a new task for this CTF


@@ 537,7 553,7 @@ async def update_login_info(ctx: discord_slash.SlashContext, URL_:str, admin_log
        enabled = True
        await ctx.send("Success.", hidden=True)

async def update_flag(ctx: discord_slash.SlashContext, flag: str, solved_prefix="✓-"):
async def update_flag(ctx: discord_slash.SlashContext, flag: str):
    """
        Updates the flag on ctfnote. To unset, simply set `flag` to the empty string.
        Handles the case where the channel name was marked as solved as well.


@@ 546,7 562,7 @@ async def update_flag(ctx: discord_slash.SlashContext, flag: str, solved_prefix=
    if current_ctf is None: return

    channel_name = ctx.channel.name
    update_flag_response = await current_ctf.getTaskByName(channel_name, solved_prefix=solved_prefix)
    update_flag_response = await current_ctf.getTaskByChannelPin(ctx)
    if update_flag_response is not None:
        update_flag_response = await update_flag_response.updateFlag(flag or "")
    return update_flag_response


@@ 584,6 600,7 @@ async def add_task(ctx: discord_slash.SlashContext, created, name: str,
        # Note: the pinned message is identified by containing the word "botdb" and "ctfnote url:".
        botdb = json.dumps({
            'ctfid': current_ctf.id,
            'chalid': result.id,
            })
        bot_data_store = f"\n||botdb:{botdb}||"
        msg = await created.send(ctfnote_url + hackmd_url + bot_data_store)


@@ 606,7 623,7 @@ async def assign_player(ctx: discord_slash.SlashContext, playername):
    else:
        user_id = user[0]['id']

    task = await current_ctf.getTaskByName(ctx.channel.name)
    task = await current_ctf.getTaskByChannelPin(ctx)
    if task is None:
        await ctx.send("This challenge does not exist on ctfnote.")
        return


@@ 662,7 679,7 @@ async def whos_leader_of_this_shit(ctx: discord_slash.SlashContext):
    if current_ctf is None: return


    task = await current_ctf.getTaskByName(ctx.channel.name)
    task = await current_ctf.getTaskByChannelPin(ctx)
    if task is None:
        await ctx.send("This challenge does not exist on ctfnote.", hidden=hide)
        return