Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix permission check for /settings log_channel #219

Merged
merged 3 commits into from
Jan 1, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
30 changes: 20 additions & 10 deletions discord-bot/bot/extensions/guild_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from aiosqlite import Connection
from bot.db.schemas import GuildSettings
from bot.utils import mention
from lightbulb.utils.permissions import permissions_in
from lightbulb.utils import permissions_in
from loguru import logger

plugin = lightbulb.Plugin("GuildSettings")
Expand Down Expand Up @@ -56,32 +56,42 @@ async def get(ctx: lightbulb.SlashContext) -> None:

@settings.child
@lightbulb.option("channel", "The channel to use.", hikari.TextableGuildChannel)
@lightbulb.command("log_channel", "Set the channel that the bot logs task and label completions in.")
@lightbulb.command("log_channel", "Set the channel that the bot logs task and label completions in.", ephemeral=True)
@lightbulb.implements(lightbulb.SlashSubCommand)
async def log_channel(ctx: lightbulb.SlashContext) -> None:
"""Set the channel that the bot logs task and label completions in."""
channel: hikari.TextableGuildChannel = ctx.options.channel
conn: Connection = ctx.bot.d.db
assert ctx.guild_id is not None # `guild_only` check
assert isinstance(channel, hikari.PermissibleGuildChannel)

# Check if the bot can send messages in that channel
assert (me := ctx.bot.get_me()) is not None # non-None after `StartedEvent`
if (own_member := ctx.bot.cache.get_member(ctx.guild_id, me.id)) is None:
own_member = await ctx.bot.rest.fetch_member(ctx.guild_id, me.id)
perms = permissions_in(channel, own_member)
if perms & ~hikari.Permissions.SEND_MESSAGES:
await ctx.respond("I don't have permission to send messages in that channel.")
assert isinstance(channel, hikari.InteractionChannel) # Slash commands are interactions
me = ctx.bot.cache.get_me() or await ctx.bot.rest.fetch_my_user()
own_member = ctx.bot.cache.get_member(ctx.guild_id, me.id) or await ctx.bot.rest.fetch_member(ctx.guild_id, me.id)

# Get the channel from the cache if it is there, otherwise fetch it
if (ch := ctx.bot.cache.get_guild_channel(channel.id)) is None:
ch = {ch.id: ch for ch in await ctx.bot.rest.fetch_guild_channels(channel.id)}[channel.id]

if not isinstance(ch, hikari.GuildTextChannel):
await ctx.respond(f"{ch.mention} is not a text channel.")
return

# if the bot's permissions for this channel don't contain SEND_MESSAGE
# This will also filter out categories and voice channels
print(permissions_in(ch, own_member) & hikari.Permissions.SEND_MESSAGES)
if not permissions_in(ch, own_member) & hikari.Permissions.SEND_MESSAGES:
await ctx.respond(f"I don't have permission to send messages in {ch.mention}.")
return

await ctx.respond(f"Setting `log_channel` to {channel.mention}.")

# update the database
async with conn.cursor() as cursor:
await cursor.execute(
"INSERT OR REPLACE INTO guild_settings (guild_id, log_channel_id) VALUES (?, ?)",
(ctx.guild_id, channel.id),
)

await conn.commit()
logger.info(f"Updated `log_channel` for {ctx.guild_id} to {channel.id}.")

Expand Down