Esempio n. 1
0
async def register(client, user: discord.user, message: discord.Message):
    db_user = db.get_db_user(user)
    db_user.registered = False
    db_user.registration_step = 1
    db.user_table.update(db_user)
    info("User not registered, setting registration step to 1", header=f"[{user}]")
    return await step1(user)
Esempio n. 2
0
async def end(client, user: discord.user, message: discord.Message):  # ends meeting by setting the meeting code to an empty string
    db_user = db.get_db_user(user)
    info("Validating Admin to end meeting")
    if db_user.discord_id in db.admins:  # admin double check
        info("ending meeting")
        meeting_code = ''
        await user.send(templates.meeting_end)
        return meeting_code, 'm'
Esempio n. 3
0
async def ctf_clear_solves(client, user: discord.user, message: discord.Message
                           ):  # ctf: tool to clear all solves in the system
    db_user = db.get_db_user(user)
    info("Iterating over each user to clear all solves")
    if db_user.discord_id in db.admins:  # admin double check
        for each_user in db.user_table.all():
            if each_user.ctf_problem_solves:
                each_user.ctf_problem_solves = []
                db.user_table.update(each_user)

    return await ctf_scoreboard_update(client, user, message)
Esempio n. 4
0
async def email(client, user: discord.user, message: discord.Message):  # sends all choate email addresses for the purposes of a mailing list
    db_user = db.get_db_user(user)
    info("Iterating over each user to get each email")
    if db_user.discord_id in db.admins: # admin double check
        emails = []
        for each_user in db.user_table.all():
            if each_user.choate_email:
                emails.append(each_user.choate_email)

    info("Sending email list")
    return await send(user, "\n".join(emails))
Esempio n. 5
0
async def get_attendance(client, user: discord.user, message: discord.Message):  # sends attendance for each user who has an attendance entry
    db_user = db.get_db_user(user)
    info("Iterating over each user to get each attendance")
    if db_user.discord_id in db.admins: # admin double check
        attendances = []
        for each_user in db.user_table.all():
            if each_user.attendance and each_user.choate_email:
                attendances.append(f'{each_user.choate_email} | {len(each_user.attendance)}')

    info("Sending Attendances")
    return await user.send("\n".join(attendances))
Esempio n. 6
0
async def ctf_flag_submit(
        client, user: discord.user,
        message: discord.Message):  # validates inputted cpuCTF flags
    db_user = db.get_db_user(user)
    info(
        f"Checking flag for {user} who tried {message.content} who has solved {db_user.ctf_problem_solves}"
    )
    for key in ctf_problems.yaml:
        try:
            if secrets.compare_digest(message.content,
                                      ctf_flags.yaml[key].strip()):
                if db_user.ctf_problem_solves is None:
                    db_user.ctf_problem_solves = []
                if key not in db_user.ctf_problem_solves:
                    info(f"Flag {message.content} accepted for {user}")
                    db_user.ctf_problem_solves.append(key)
                    db.user_table.update(db_user)
                    return await user.send(templates.ctf_flag_acceptance)
                else:
                    info(f"Flag {message.content} already accepted for {user}")
                    return await user.send(templates.ctf_flag_already_solved)
        except KeyError:
            pass
    info(f"Flag {message.content} rejected for {user}")
    return await user.send(templates.ctf_flag_rejection)
Esempio n. 7
0
async def ctf_get_solves(
    client, user: discord.user, message: discord.Message
):  # ctf: debugging tool to check who solved what problems
    db_user = db.get_db_user(user)
    info("Iterating over each user to get all solves")
    if db_user.discord_id in db.admins:  # admin double check
        solves = []
        for each_user in db.user_table.all():
            if each_user.ctf_problem_solves and each_user.choate_email:
                solves.append(
                    f'{each_user.choate_email} | {len(each_user.ctf_problem_solves)}'
                )

    info("Sending Solves")
    return await user.send("\n".join(solves))
Esempio n. 8
0
    def find(self, client) -> discord.TextChannel:
        from bot.bot_client import CPUBotClient

        client: CPUBotClient

        for channel in client.guild.channels:
            if isinstance(channel, discord.TextChannel):
                if self.id == channel.id:
                    info(
                        f"Text channel with id {self.id} has been found",
                        header=f"[{self.name}]",
                    )
                    return channel

        error(f"Text channel with id {self.id} not found", header=f"[{self.name}]")
Esempio n. 9
0
async def handle_dm(client, user: discord.User, message: discord.Message):
    responses = []

    for each_command, function in direct_commands:
        if bool(re.fullmatch(each_command, message.content)):
            info(each_command + " command function executed", header=f"[{user}]")
            responses.append(await function(client, user, message))

    if db.check_admin(user):
        for each_command, function in admin_direct_commands:
            if bool(re.fullmatch(each_command, message.content)):
                info(each_command + " command function executed by " + db.get_db_user(user).choate_email + " for " + str(message.content))
                responses.append(await function(client, user, message))

    return responses
Esempio n. 10
0
async def step0(client, user: discord.User, db_user: DBUser):
    from bot.bot_client import CPUBotClient

    client: CPUBotClient

    # Create embed
    info_embed = discord.Embed(title="User Info", color=0x0000FF)
    info_embed.add_field(name="__First Name__", value=db_user.first_name)
    info_embed.add_field(name="__Last Name__", value=db_user.last_name)
    info_embed.add_field(name="__Choate Email__", value=db_user.choate_email)

    # Send message and add reactions
    message = await send(user, templates.welcome_back, embed=info_embed)
    await message.add_reaction("πŸ‘")
    await message.add_reaction("πŸ‘Ž")
    info("Verification message sent, waiting for user reaction...", header=f"[{user}]")

    # Wait for user reaction
    def check(r: discord.Reaction, u: discord.User):
        return (
            r.message.id == message.id
            and r.emoji in ["πŸ‘", "πŸ‘Ž"]
            and u.id != client.user.id
        )

    res = await client.wait_for("reaction_add", check=check)
    reaction: discord.reaction = res[0]
    info(f"User reacted with emoji '{reaction.emoji}'", header=f"[{user}]")

    if reaction.emoji == "πŸ‘":
        await message.remove_reaction("πŸ‘", client.user)
        await message.remove_reaction("πŸ‘Ž", client.user)
        db_user.registered = True
        db_user.registration_step = 5
        user_table.update(db_user)
        await step5(client, user, db_user)

    elif reaction.emoji == "πŸ‘Ž":
        await message.remove_reaction("πŸ‘", client.user)
        await message.remove_reaction("πŸ‘Ž", client.user)
        db_user.registered = False
        db_user.registration_step = 1
        user_table.update(db_user)
        await send(user, templates.reset)
        await step1(user, user)
Esempio n. 11
0
async def start(client, user: discord.user, message: discord.Message):  # begins meeting by generating attendance code and setting it to be active
    db_user = db.get_db_user(user)
    info("Validating Admin to Create meeting Code")
    if db_user.discord_id in db.admins: # admin double check
        info("Checking for existing code")
        if not client.meeting_id:
            info("Creating Code")
            meeting_code = secrets.token_hex(4)
            info(f"Code: {meeting_code}")
            await user.send(templates.attendance_set + meeting_code)
            return meeting_code, 'm'
        else:
            return await user.send(templates.attendance_set_failed)
Esempio n. 12
0
    async def on_message(self, message: discord.Message):
        if isinstance(message.channel, discord.DMChannel):
            if isinstance(message.author, discord.User) and not str(message.author) == BOT:
                responses = await commands.handle_dm(self, message.author, message)

                if len(responses) == 0:  # No commands were executed
                    executed = False
                    if not get_db_user(message.author).registered:  # is registered
                        executed = await register.handle_dm(self, message.author, message)

                    if not executed: # Nothing really happened
                        # await message.author.send(templates.help)
                        await commands.send(message.author, templates.help)
                        await message.author.send(templates.help)
                else: # meeting attendance code
                    if type(responses[0]) is tuple: # ask Spencer what's happening here
                        if len(responses[0]) == 2:
                            if responses[0][1] == 'm':
                                info(f"Meeting Code set to {responses[0][0]}")
                                self.meeting_id = responses[0][0]
Esempio n. 13
0
async def ctf_scoreboard_update(client, user: discord.user,
                                message: discord.Message):
    db_user = db.get_db_user(user)
    if db_user.discord_id in db.admins:  # admin double check
        problem_solves = {}
        info("Iterating over each problem for setup")
        for item in ctf_problems.yaml:
            problem_solves[item] = 0
        info("Iterating over each user to get all solves")
        for each_user in db.user_table.all():
            if each_user.ctf_problem_solves:
                for item in problem_solves:
                    if item in each_user.ctf_problem_solves:
                        problem_solves[item] += 1
        info("Iterating over each user to setup scoreboard")
        client.ctf_scoreboard = []
        for each_user in db.user_table.all():
            if each_user.ctf_problem_solves and each_user.first_name and each_user.last_name:
                user_points = 0
                for problem in each_user.ctf_problem_solves:
                    if problem_solves[problem]:
                        user_points += round(client.ctf_point_value /
                                             problem_solves[problem])
                client.ctf_scoreboard.append((
                    f"{each_user.first_name} {each_user.last_name}: {user_points} points",
                    user_points))
        client.ctf_scoreboard = sorted(client.ctf_scoreboard,
                                       key=lambda x: x[1],
                                       reverse=True)
    return await ctf_scoreboard_get(client, user, message)
Esempio n. 14
0
async def finish_registration(client, user: discord.User, db_user: DBUser):
    from bot.bot_client import CPUBotClient

    client: CPUBotClient

    info("Finishing user registration", header=f"[{user}]")
    db_user.registered = True
    user_table.update(db_user)

    member: discord.Member
    for member in client.guild.members:
        if member.id == user.id:
            break
    else:
        error(f"User not found in guild, cannot complete registration", header=f"[{user}]")
        return

    try:
        await member.edit(nick=f"{db_user.first_name} {db_user.last_name}")
        await member.add_roles(client.club_member_role)
    except discord.Forbidden:
        error("User registered, but bot lacks permission to edit user, are they the server owner?", header=f"[{user}]")

    await welcome_user(client, member)
Esempio n. 15
0
async def attendance(client, user: discord.user, message: discord.Message):  #called upon attendance code dm, the attendance code is then added to a list of attended meetings by that user
    db_user = db.get_db_user(user)
    info(f"Checking meeting id {client.meeting_id} for {user} who said {message.content}")
    if secrets.compare_digest(message.content, client.meeting_id):
        info(f"Approved meeting id for {user}")
        if db_user.attendance is None:
            db_user.attendance = []
        if client.meeting_id not in db_user.attendance:
            info(f'Added meeting id to {user}')
            db_user.attendance.append(client.meeting_id)
            db.user_table.update(db_user)
            return await user.send(templates.attendance)
        return await user.send(templates.attendance_found)
Esempio n. 16
0
async def handle_join_server(client, user: discord.Member):
    db_user = get_db_user(user)

    info("Added user to database", header=f"[{user}]")

    if db_user.registered:
        db_user.registration_step = 0
        user_table.update(db_user)
        info("User has already registered, setting registration step to 0", header=f"[{user}]")
        await step0(client, user, db_user)
    else:
        db_user.registration_step = 1
        user_table.update(db_user)
        info("User not registered, setting registration step to 1", header=f"[{user}]")
        await step1(user)
Esempio n. 17
0
async def step4(client, user: discord.User, db_user: DBUser):
    from bot.bot_client import CPUBotClient

    client: CPUBotClient

    # Create Embed
    info_embed = discord.Embed(title="User Info", color=0x0000FF)
    info_embed.add_field(name="__First Name__", value=db_user.first_name)
    info_embed.add_field(name="__Last Name__", value=db_user.last_name)
    info_embed.add_field(name="__Choate Email__", value=db_user.choate_email)

  # Nothing really happened   # Send message and add reactions
    message = await send(user,
        f"""Thanks! Is all of this info correct?""", embed=info_embed
    )
    await message.add_reaction("πŸ‘")
    await message.add_reaction("πŸ‘Ž")
    info("Verification message sent", header=f"[{user}]")

    # Wait for user reaction
    def check(r: discord.Reaction, u: discord.User):
        return (
            r.message.id == message.id
            and r.emoji in ["πŸ‘", "πŸ‘Ž"]
            and u.id != client.user.id
        )

    res = await client.wait_for("reaction_add", check=check)
    reaction: discord.reaction = res[0]
    info(f"User reacted with emoji '{reaction.emoji}'", header=f"[{user}]")

    if reaction.emoji == "πŸ‘":
        await message.remove_reaction("πŸ‘", client.user)
        await message.remove_reaction("πŸ‘Ž", client.user)
        db_user.registration_step = 5
        user_table.update(db_user)
        await step5(client, user, db_user)

    elif reaction.emoji == "πŸ‘Ž":
        await message.remove_reaction("πŸ‘", client.user)
        await message.remove_reaction("πŸ‘Ž", client.user)
        await send(user, "Ok, asking for the info again.")
        info("User rejected the info, restarting at step 1", header=f"[{user}]")
        db_user.registration_step = 1
        user_table.update(db_user)
        await step1(user, welcome=False)
Esempio n. 18
0
    async def setup(self, client) -> discord.Role:
        from bot.bot_client import CPUBotClient

        client: CPUBotClient

        role = await self._find(client)

        if role is None:
            info(
                f"{self.name} role not found, creating one now...",
                header=f"[{self.name}]",
            )
            role = await self._create(client)
            info(
                f"{self.name} role has been created, you should update its perms",
                header=f"[{self.name}]",
            )
        else:
            info(f"{self.name} role found, skipping creation",
                 header=f"[{self.name}]")

        return role
Esempio n. 19
0
async def step3_input(client, user: discord.User, db_user: DBUser, choate_email: str):
    info(f'User provided Choate email "{choate_email}"', header=f"[{user}]")
    db_user.choate_email = choate_email
    db_user.registration_step = 4
    user_table.update(db_user)
    await step4(client, user, db_user)
Esempio n. 20
0
    async def on_member_join(self, member: discord.Member):
        if member.guild.id != self.guild.id:
            return

        info(f"{member} has joined the server", header=f"[{member}]")
        await register.handle_join_server(self, member)
Esempio n. 21
0
    async def on_ready(self):
        info("Client connected to discord")

        for guild in self.guilds:
            if guild.id == DISCORD_GUILD_ID:
                self.guild = guild
                break

        if self.guild is None:
            error(f"Guild with id {DISCORD_GUILD_ID} not found")
            exit(-1)

        info(f"Guild with id {DISCORD_GUILD_ID} found, name={self.guild.name}")

        await roles.setup_guild_roles(self)
        await channels.setup_guild_channels(self)

        info("Checking existing guild members...")
        for member in self.guild.members:
            member: discord.Member
            if db_user := user_table.find_discord_user(member):
                if db_user.registered:
                    if self.club_member_role in member.roles:
                        info("Existing member found in db, already has Club Member role", header=f"[{member}]")
                    else:
                        try:
                            await member.add_roles(self.club_member_role)
                        except discord.Forbidden:
                            error("Existing member found in db, but bot lacks permission to give "
                                  "Club Member role to this user.", header=f"[{member}]")
                        else:
                            info("Existing member found in db, bot gave user Club Member role", header=f"[{member}]")
                else:
                    if self.club_member_role in member.roles:
                        warning("Unregistered member found in db, has Club Member role for some reason", header=f"[{member}]")
                    else:
                        info("Unregistered member found in db, doesn't has Club Member role", header=f"[{member}]")
            else:
                info("User not found in db", header=f"[{member}]")
Esempio n. 22
0
async def step2_input(user: discord.User, db_user: DBUser, last_name: str):
    info(f'User provided last name "{last_name}"', header=f"[{user}]")
    db_user.last_name = last_name
    db_user.registration_step = 3
    user_table.update(db_user)
    await step3(user, db_user)
Esempio n. 23
0
async def step1_input(user: discord.User, db_user: DBUser, first_name: str):
    info(f'User provided first name "{first_name}"', header=f"[{user}]")
    db_user.first_name = first_name
    db_user.registration_step = 2
    user_table.update(db_user)
    await step2(user, db_user)