Fix permissions, closes #19. Also closes #22, closes #23, closes #24

This commit is contained in:
Zeva Rose 2021-07-01 18:05:00 -06:00
parent c3e2666cb6
commit ef54a046e0
8 changed files with 160 additions and 215 deletions

View file

@ -6,6 +6,7 @@ from discord.utils import get
from discord_slash import cog_ext from discord_slash import cog_ext
from discord_slash.utils.manage_commands import create_option, create_choice from discord_slash.utils.manage_commands import create_option, create_choice
from jarvis.utils.db import DBManager from jarvis.utils.db import DBManager
from jarvis.utils.permissions import admin_or_permissions
class AdminCog(commands.Cog): class AdminCog(commands.Cog):
@ -30,6 +31,7 @@ class AdminCog(commands.Cog):
): ):
if not user or user == ctx.author: if not user or user == ctx.author:
await ctx.send("You cannot ban yourself.") await ctx.send("You cannot ban yourself.")
return
if not reason: if not reason:
reason = ( reason = (
"Mr. Stark is displeased with your presence. Please leave." "Mr. Stark is displeased with your presence. Please leave."
@ -76,7 +78,7 @@ class AdminCog(commands.Cog):
@cog_ext.cog_slash( @cog_ext.cog_slash(
name="ban", name="ban",
description="Ban a user", description="Ban a user",
guild_ids=[578757004059738142], guild_ids=[418094694325813248, 578757004059738142],
options=[ options=[
create_option( create_option(
name="user", name="user",
@ -109,7 +111,7 @@ class AdminCog(commands.Cog):
), ),
], ],
) )
@commands.has_permissions(ban_members=True) @admin_or_permissions(ban_members=True)
async def _ban_slash( async def _ban_slash(
self, self,
ctx, ctx,
@ -123,6 +125,7 @@ class AdminCog(commands.Cog):
async def _kick(self, ctx, user: User, reason=None): async def _kick(self, ctx, user: User, reason=None):
if not user or user == ctx.author: if not user or user == ctx.author:
await ctx.send("You cannot kick yourself.") await ctx.send("You cannot kick yourself.")
return
if not reason: if not reason:
reason = ( reason = (
"Mr. Stark is displeased with your presence. Please leave." "Mr. Stark is displeased with your presence. Please leave."
@ -152,7 +155,7 @@ class AdminCog(commands.Cog):
@cog_ext.cog_slash( @cog_ext.cog_slash(
name="kick", name="kick",
description="Kick a user", description="Kick a user",
guild_ids=[578757004059738142], guild_ids=[418094694325813248, 578757004059738142],
options=[ options=[
create_option( create_option(
name="user", name="user",
@ -168,7 +171,7 @@ class AdminCog(commands.Cog):
), ),
], ],
) )
@commands.has_permissions(kick_members=True) @admin_or_permissions(kick_members=True)
async def _kick_slash(self, ctx, user: User, reason=None): async def _kick_slash(self, ctx, user: User, reason=None):
await self._kick(ctx, user, reason) await self._kick(ctx, user, reason)
@ -201,7 +204,7 @@ class AdminCog(commands.Cog):
) )
], ],
) )
@commands.has_permissions(manage_messages=True) @admin_or_permissions(manage_messages=True)
async def _purge_slash(self, ctx, amount: int = 10): async def _purge_slash(self, ctx, amount: int = 10):
if amount < 1: if amount < 1:
await ctx.send("Amount must be >= 1") await ctx.send("Amount must be >= 1")
@ -212,7 +215,7 @@ class AdminCog(commands.Cog):
@cog_ext.cog_slash( @cog_ext.cog_slash(
name="mute", name="mute",
description="Mute a user", description="Mute a user",
guild_ids=[578757004059738142], guild_ids=[418094694325813248, 578757004059738142],
options=[ options=[
create_option( create_option(
name="user", name="user",
@ -234,7 +237,7 @@ class AdminCog(commands.Cog):
), ),
], ],
) )
@commands.has_permissions(mute_members=True) @admin_or_permissions(mute_members=True)
async def _mute(self, ctx, user: Member, reason: str, length: int = 30): async def _mute(self, ctx, user: Member, reason: str, length: int = 30):
mute_setting = self.db.jarvis.settings.find_one( mute_setting = self.db.jarvis.settings.find_one(
{"guild": ctx.guild.id, "setting": "mute"} {"guild": ctx.guild.id, "setting": "mute"}

View file

@ -1,12 +1,11 @@
import jarvis import jarvis
import re import re
from datetime import datetime from datetime import datetime
from discord import TextChannel, Emoji from discord import TextChannel
from discord.ext import commands from discord.ext import commands
from discord.utils import find from discord.utils import find
from discord_slash import cog_ext from discord_slash import cog_ext
from discord_slash.utils.manage_commands import create_option from discord_slash.utils.manage_commands import create_option
from emoji import UNICODE_EMOJI
from jarvis.config import get_config from jarvis.config import get_config
from jarvis.utils.db import DBManager from jarvis.utils.db import DBManager
@ -54,6 +53,29 @@ class AutoReactCog(commands.Cog):
self.db.jarvis.autoreact.insert_one(autoreact) self.db.jarvis.autoreact.insert_one(autoreact)
await ctx.send(f"Autoreact created for {channel.mention}!") await ctx.send(f"Autoreact created for {channel.mention}!")
@cog_ext.cog_subcommand(
base="autoreact",
name="remove",
description="Remove an autoreact from a channel",
guild_ids=[418094694325813248, 578757004059738142],
options=[
create_option(
name="channel",
description="Channel to stop monitoring",
option_type=7,
required=True,
)
],
)
async def _autoreact_remove(self, ctx, channel: TextChannel):
exists = self.db.jarvis.autoreact.delete_one(
{"guild": channel.guild.id, "channel": channel.id}
)
if exists:
await ctx.send(f"Autoreact remove from {channel.mention}")
else:
await ctx.send(f"Autoreact not found on {channel.mention}")
@cog_ext.cog_subcommand( @cog_ext.cog_subcommand(
base="autoreact", base="autoreact",
name="add", name="add",
@ -103,6 +125,11 @@ class AutoReactCog(commands.Cog):
f"Emote already added to {channel.mention} autoreactions." f"Emote already added to {channel.mention} autoreactions."
) )
return return
if len(exists["reactions"]) == 20:
await ctx.send(
"Max number of reactions hit. Remove a different one to add this one"
)
return
exists["reactions"].append(emote) exists["reactions"].append(emote)
self.db.jarvis.autoreact.update_one( self.db.jarvis.autoreact.update_one(
{"_id": exists["_id"]}, {"_id": exists["_id"]},

View file

@ -13,8 +13,9 @@ from bson import ObjectId
from discord.ext import commands from discord.ext import commands
from discord_slash import cog_ext from discord_slash import cog_ext
from inspect import getsource from inspect import getsource
from jarvis.utils import build_embed, convert_bytesize, user_is_bot_admin from jarvis.utils import build_embed, convert_bytesize
from jarvis.utils.field import Field from jarvis.utils.field import Field
from jarvis.utils.permissions import user_is_bot_admin
from time import time from time import time

View file

@ -3,7 +3,8 @@ import jarvis
from discord import User from discord import User
from discord.ext import commands from discord.ext import commands
from jarvis.config import get_config, reload_config from jarvis.config import get_config, reload_config
from jarvis.utils import update, user_is_bot_admin, db from jarvis.utils import update, db
from jarvis.utils.permissions import user_is_bot_admin
class OwnerCog(commands.Cog): class OwnerCog(commands.Cog):

View file

@ -4,8 +4,9 @@ from discord import Role
from discord.ext import commands from discord.ext import commands
from discord_slash import cog_ext from discord_slash import cog_ext
from discord_slash.utils.manage_commands import create_option from discord_slash.utils.manage_commands import create_option
from jarvis.config import get_config, reload_config from jarvis.config import get_config
from jarvis.utils import update, user_is_bot_admin, db from jarvis.utils import db
from jarvis.utils.permissions import admin_or_permissions
class SettingsCog(commands.Cog): class SettingsCog(commands.Cog):
@ -38,7 +39,7 @@ class SettingsCog(commands.Cog):
) )
], ],
) )
@commands.has_permissions(mute_members=True) @admin_or_permissions(mute_members=True)
async def _mute(self, ctx, role: Role): async def _mute(self, ctx, role: Role):
await ctx.defer() await ctx.defer()
self.update_settings("mute", role.id, ctx.guild.id) self.update_settings("mute", role.id, ctx.guild.id)

View file

@ -11,6 +11,7 @@ from jarvis.config import get_config
from jarvis.utils import build_embed from jarvis.utils import build_embed
from jarvis.utils.db import DBManager from jarvis.utils.db import DBManager
from jarvis.utils.field import Field from jarvis.utils.field import Field
from jarvis.utils.permissions import admin_or_permissions
supported_images = [ supported_images = [
"image/png", "image/png",
@ -40,7 +41,7 @@ class StarboardCog(commands.Cog):
if starboards != []: if starboards != []:
message = "Available Starboards:\n" message = "Available Starboards:\n"
for s in starboards: for s in starboards:
message += f"{s['name']}: <#{s['target']}>\n" message += f"<#{s['target']}>\n"
await ctx.send(message) await ctx.send(message)
else: else:
await ctx.send("No Starboards available.") await ctx.send("No Starboards available.")
@ -51,12 +52,6 @@ class StarboardCog(commands.Cog):
description="Create a starboard", description="Create a starboard",
guild_ids=[418094694325813248, 578757004059738142], guild_ids=[418094694325813248, 578757004059738142],
options=[ options=[
create_option(
name="name",
description="Starboard name",
option_type=3,
required=True,
),
create_option( create_option(
name="target", name="target",
description="Target channel", description="Target channel",
@ -66,33 +61,28 @@ class StarboardCog(commands.Cog):
], ],
) )
@commands.has_permissions(administrator=True) @commands.has_permissions(administrator=True)
async def _create(self, ctx, name: str, target: TextChannel): async def _create(self, ctx, target: TextChannel):
if target not in ctx.guild.channels: if target not in ctx.guild.channels:
await ctx.send( await ctx.send(
"Target channel not in guild. Choose an existing channel." "Target channel not in guild. Choose an existing channel."
) )
return return
exists = self.db.jarvis.starboard.find_one( exists = self.db.jarvis.starboard.find_one(
{"name": name, "guild": ctx.guild.id} {"target": target.id, "guild": ctx.guild.id}
) )
if exists: if exists:
await ctx.send( await ctx.send(f"Starboard already exists at {target.mention}.")
f"Starboard {name} already exists at <@{exists['channel']}>!"
)
return return
self.db.jarvis.starboard.insert_one( self.db.jarvis.starboard.insert_one(
{ {
"name": name,
"guild": ctx.guild.id, "guild": ctx.guild.id,
"target": target.id, "target": target.id,
"admin": ctx.author.id, "admin": ctx.author.id,
"time": datetime.now(), "time": datetime.now(),
} }
) )
await ctx.send( await ctx.send(f"Starboard created. Check it out at {target.mention}.")
f"Starboard `{name}` created! Check it out at {target.mention}."
)
@cog_ext.cog_subcommand( @cog_ext.cog_subcommand(
base="starboard", base="starboard",
@ -101,112 +91,26 @@ class StarboardCog(commands.Cog):
guild_ids=[418094694325813248, 578757004059738142], guild_ids=[418094694325813248, 578757004059738142],
options=[ options=[
create_option( create_option(
name="name", name="channel",
description="Starboard name", description="Starboard channel",
option_type=3,
required=True,
),
],
)
@commands.has_permissions(administrator=True)
async def _delete(self, ctx, name: str):
deleted = self.db.jarvis.starboard.delete_one(
{
"name": name,
"guild": ctx.guild.id,
}
)
if deleted:
self.db.jarvis.stars.delete_many({"starboard": name})
await ctx.send(f"Starboard `{name}` deleted!")
else:
await ctx.send(f"Starboard `{name}` not found!")
@cog_ext.cog_subcommand(
base="starboard",
name="move",
description="Move a starboard",
guild_ids=[418094694325813248, 578757004059738142],
options=[
create_option(
name="name",
description="Starboard name",
option_type=3,
required=True,
),
create_option(
name="target",
description="New Starboard channel",
option_type=7, option_type=7,
required=True, required=True,
), ),
], ],
) )
@commands.has_permissions(administrator=True) @commands.has_permissions(administrator=True)
async def _move(self, ctx, name: str, target: TextChannel): async def _delete(self, ctx, target: TextChannel):
exists = self.db.jarvis.starboard.find_one( deleted = self.db.jarvis.starboard.delete_one(
{ {
"name": name, "target": target.id,
"guild": ctx.guild.id, "guild": ctx.guild.id,
} }
) )
if not exists: if deleted:
await ctx.send( self.db.jarvis.stars.delete_many({"starboard": target.id})
f"Good news! Starboard `{name}` doesn't exist!\n" await ctx.send(f"Starboard deleted from {target.mention}.")
+ f"Run `/starboard create {name} {target.mention}` " else:
+ "to create it!" await ctx.send(f"Starboard not found in {target.mention}.")
)
return
exists["target"] = target.id
self.db.jarvis.starboard.update_one(
{"_id": exists["_id"]}, {"$set": exists}
)
await ctx.send(f"Starboard `{name}` moved to {target.mention}!")
@cog_ext.cog_subcommand(
base="starboard",
name="rename",
description="Move a starboard",
guild_ids=[418094694325813248, 578757004059738142],
options=[
create_option(
name="name",
description="Starboard name",
option_type=3,
required=True,
),
create_option(
name="new",
description="New Starboard name",
option_type=3,
required=True,
),
],
)
@commands.has_permissions(administrator=True)
async def _rename(self, ctx, name: str, new: str):
old_exists = self.db.jarvis.starboard.find_one(
{"name": name, "guild": ctx.guild.id}
)
if not old_exists:
await ctx.send(
f"Good news! Starboard `{name}` doesn't exist!\n"
+ f"Run `/starboard create {new} <target channel>` "
+ "to create your new channel!"
)
return
new_exists = self.db.jarvis.starboard.find_one(
{"name": new, "guild": ctx.guild.id}
)
if new_exists:
await ctx.send(f"Starboard `{new}` already exists!")
return
old_exists["name"] = new
self.db.jarvis.starboard.update_one(
{"_id": old_exists["_id"]}, {"$set": old_exists}
)
await ctx.send(f"Starboard `{name}` moved renamed to `{name}`!")
@cog_ext.cog_subcommand( @cog_ext.cog_subcommand(
base="star", base="star",
@ -223,7 +127,7 @@ class StarboardCog(commands.Cog):
create_option( create_option(
name="starboard", name="starboard",
description="Starboard to send message to", description="Starboard to send message to",
option_type=3, option_type=7,
required=True, required=True,
), ),
create_option( create_option(
@ -240,40 +144,36 @@ class StarboardCog(commands.Cog):
self, self,
ctx: SlashContext, ctx: SlashContext,
message: str, message: str,
starboard: str, starboard: TextChannel,
channel: TextChannel = None, channel: TextChannel = None,
): ):
if not channel: if not channel:
channel = ctx.channel channel = ctx.channel
exists = self.db.jarvis.starboard.find_one( exists = self.db.jarvis.starboard.find_one(
{"name": starboard, "guild": ctx.guild.id} {"target": starboard.id, "guild": ctx.guild.id}
) )
if not exists: if not exists:
await ctx.send( await ctx.send(
f"Starboard `{starboard}` does not exist! " f"Starboard does not exist in {starboard.mention}. "
+ "Please create it first" + "Please create it first"
) )
return return
message = await channel.fetch_message(int(message)) message = await channel.fetch_message(int(message))
guild_channels = await ctx.guild.fetch_channels()
target = find(lambda x: x.id == exists["target"], guild_channels)
if not target:
await ctx.send("Could not find Starboard channel!")
return
exists = self.db.jarvis.stars.find_one( exists = self.db.jarvis.stars.find_one(
{ {
"message": message.id, "message": message.id,
"channel": message.channel.id, "channel": message.channel.id,
"guild": message.guild.id, "guild": message.guild.id,
"starboard": starboard, "starboard": starboard.id,
} }
) )
if exists: if exists:
await ctx.send(f"Message already sent to Starboard `{starboard}`!") await ctx.send(
f"Message already sent to Starboard {starboard.mention}"
)
return return
content = message.content content = message.content
@ -306,14 +206,14 @@ class StarboardCog(commands.Cog):
if image_url: if image_url:
embed.set_image(url=image_url) embed.set_image(url=image_url)
star = await target.send(embed=embed) star = await starboard.send(embed=embed)
self.db.jarvis.stars.insert_one( self.db.jarvis.stars.insert_one(
{ {
"message": message.id, "message": message.id,
"channel": message.channel.id, "channel": message.channel.id,
"guild": message.guild.id, "guild": message.guild.id,
"starboard": starboard, "starboard": starboard.id,
"admin": ctx.author.id, "admin": ctx.author.id,
"time": datetime.now(), "time": datetime.now(),
"star": star.id, "star": star.id,
@ -321,8 +221,7 @@ class StarboardCog(commands.Cog):
) )
await ctx.send( await ctx.send(
f"Message saved to Starboard `{starboard}`!\n" "Message saved to Starboard.\n" + f"See it in {starboard.mention}"
+ f"See it in {target.mention}"
) )

View file

@ -86,13 +86,3 @@ def update():
def get_repo_hash(): def get_repo_hash():
repo = git.Repo(".") repo = git.Repo(".")
return repo.head.object.hexsha return repo.head.object.hexsha
def user_is_bot_admin():
def predicate(ctx):
if getattr(jarvis.config.get_config(), "admins", None):
return ctx.author.id in jarvis.config.get_config().admins
else:
return False
return commands.check(predicate)

View file

@ -0,0 +1,23 @@
import jarvis
from discord.ext import commands
def user_is_bot_admin():
def predicate(ctx):
if getattr(jarvis.config.get_config(), "admins", None):
return ctx.author.id in jarvis.config.get_config().admins
else:
return False
return commands.check(predicate)
def admin_or_permissions(**perms):
original = commands.has_permissions(**perms).predicate
async def extended_check(ctx):
return await commands.has_permissions(administrator=True).predicate(
ctx
) or await original(ctx)
return commands.check(extended_check)