aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar scragly <[email protected]>2019-02-22 16:59:19 +1000
committerGravatar GitHub <[email protected]>2019-02-22 16:59:19 +1000
commit301e877beff8436de0b0d6f3360e3bcf0d81bf01 (patch)
treed6a2a8b0184a014c51afa9a7c468c1660fce8270
parentMerge pull request #312 from python-discord/fix-create-team (diff)
parentLinting corrections. (diff)
Merge pull request #313 from python-discord/Hemlock.Users_and_Roles_adjustment
Use of Constants and Adjusting !user permissions
-rw-r--r--bot/cogs/antispam.py6
-rw-r--r--bot/cogs/bigbrother.py18
-rw-r--r--bot/cogs/bot.py7
-rw-r--r--bot/cogs/clean.py14
-rw-r--r--bot/cogs/cogs.py12
-rw-r--r--bot/cogs/deployment.py4
-rw-r--r--bot/cogs/doc.py6
-rw-r--r--bot/cogs/information.py9
-rw-r--r--bot/cogs/moderation.py3
-rw-r--r--bot/cogs/snekbox.py6
-rw-r--r--bot/cogs/superstarify.py8
-rw-r--r--bot/cogs/tags.py5
-rw-r--r--bot/cogs/utils.py6
-rw-r--r--bot/cogs/wolfram.py11
-rw-r--r--bot/constants.py2
15 files changed, 60 insertions, 57 deletions
diff --git a/bot/cogs/antispam.py b/bot/cogs/antispam.py
index 0d1c7c1e9..f65dbe8ab 100644
--- a/bot/cogs/antispam.py
+++ b/bot/cogs/antispam.py
@@ -11,7 +11,8 @@ from bot.cogs.modlog import ModLog
from bot.constants import (
AntiSpam as AntiSpamConfig, Channels,
Colours, DEBUG_MODE, Event,
- Guild as GuildConfig, Icons, Roles,
+ Guild as GuildConfig, Icons,
+ Roles, STAFF_ROLES,
)
@@ -35,7 +36,6 @@ WHITELISTED_CHANNELS = (
Channels.helpers, Channels.message_log,
Channels.mod_alerts, Channels.modlog, Channels.staff_lounge
)
-WHITELISTED_ROLES = (Roles.owner, Roles.admin, Roles.moderator, Roles.helpers)
class AntiSpam:
@@ -57,7 +57,7 @@ class AntiSpam:
or message.guild.id != GuildConfig.id
or message.author.bot
or (message.channel.id in WHITELISTED_CHANNELS and not DEBUG_MODE)
- or (message.author.top_role.id in WHITELISTED_ROLES and not DEBUG_MODE)
+ or (message.author.top_role.id in STAFF_ROLES and not DEBUG_MODE)
):
return
diff --git a/bot/cogs/bigbrother.py b/bot/cogs/bigbrother.py
index f07289985..03d2f1d42 100644
--- a/bot/cogs/bigbrother.py
+++ b/bot/cogs/bigbrother.py
@@ -9,7 +9,11 @@ from aiohttp import ClientError
from discord import Color, Embed, Guild, Member, Message, TextChannel, User
from discord.ext.commands import Bot, Context, command, group
-from bot.constants import BigBrother as BigBrotherConfig, Channels, Emojis, Guild as GuildConfig, Keys, Roles, URLs
+from bot.constants import (
+ BigBrother as BigBrotherConfig, Channels, Emojis,
+ Guild as GuildConfig, Keys,
+ MODERATION_ROLES, STAFF_ROLES, URLs
+)
from bot.decorators import with_role
from bot.pagination import LinePaginator
from bot.utils import messages
@@ -295,14 +299,14 @@ class BigBrother:
await ctx.send(f":x: the API returned an error: {error_reason}")
@group(name='bigbrother', aliases=('bb',), invoke_without_command=True)
- @with_role(Roles.owner, Roles.admin, Roles.moderator)
+ @with_role(*MODERATION_ROLES)
async def bigbrother_group(self, ctx: Context):
"""Monitor users, NSA-style."""
await ctx.invoke(self.bot.get_command("help"), "bigbrother")
@bigbrother_group.command(name='watched', aliases=('all',))
- @with_role(Roles.owner, Roles.admin, Roles.moderator)
+ @with_role(*MODERATION_ROLES)
async def watched_command(self, ctx: Context, from_cache: bool = True):
"""
Shows all users that are currently monitored and in which channel.
@@ -340,7 +344,7 @@ class BigBrother:
await ctx.send(f":x: got non-200 response from the API")
@bigbrother_group.command(name='watch', aliases=('w',))
- @with_role(Roles.owner, Roles.admin, Roles.moderator)
+ @with_role(*MODERATION_ROLES)
async def watch_command(self, ctx: Context, user: User, *, reason: str):
"""
Relay messages sent by the given `user` to the `#big-brother-logs` channel
@@ -354,7 +358,7 @@ class BigBrother:
await self._watch_user(ctx, user, reason, channel_id)
@bigbrother_group.command(name='unwatch', aliases=('uw',))
- @with_role(Roles.owner, Roles.admin, Roles.moderator)
+ @with_role(*MODERATION_ROLES)
async def unwatch_command(self, ctx: Context, user: User):
"""Stop relaying messages by the given `user`."""
@@ -378,7 +382,7 @@ class BigBrother:
await ctx.send(f":x: the API returned an error: {reason}")
@bigbrother_group.command(name='nominate', aliases=('n',))
- @with_role(Roles.owner, Roles.admin, Roles.moderator)
+ @with_role(*MODERATION_ROLES)
async def nominate_command(self, ctx: Context, user: User, *, reason: str):
"""
Nominates a user for the helper role by adding them to the talent-pool channel
@@ -401,7 +405,7 @@ class HelperNomination:
self.bot = bot
@command(name='nominate', aliases=('n',))
- @with_role(Roles.owner, Roles.admin, Roles.moderator, Roles.helpers)
+ @with_role(*STAFF_ROLES)
async def nominate_command(self, ctx: Context, user: User, *, reason: str):
"""
Nominates a user for the helper role by adding them to the talent-pool channel
diff --git a/bot/cogs/bot.py b/bot/cogs/bot.py
index a6d9aa278..61bad422d 100644
--- a/bot/cogs/bot.py
+++ b/bot/cogs/bot.py
@@ -8,7 +8,8 @@ from discord.ext.commands import Bot, Context, command, group
from dulwich.repo import Repo
from bot.constants import (
- Channels, Guild, Roles, URLs
+ Channels, Guild, MODERATION_ROLES,
+ Roles, URLs,
)
from bot.decorators import with_role
from bot.utils.messages import wait_for_deletion
@@ -81,7 +82,7 @@ class Bot:
await ctx.send(embed=embed)
@command(name='echo', aliases=('print',))
- @with_role(Roles.owner, Roles.admin, Roles.moderator)
+ @with_role(*MODERATION_ROLES)
async def echo_command(self, ctx: Context, *, text: str):
"""
Send the input verbatim to the current channel
@@ -90,7 +91,7 @@ class Bot:
await ctx.send(text)
@command(name='embed')
- @with_role(Roles.owner, Roles.admin, Roles.moderator)
+ @with_role(*MODERATION_ROLES)
async def embed_command(self, ctx: Context, *, text: str):
"""
Send the input within an embed to the current channel
diff --git a/bot/cogs/clean.py b/bot/cogs/clean.py
index 8a9b01d07..b34d1118b 100644
--- a/bot/cogs/clean.py
+++ b/bot/cogs/clean.py
@@ -9,7 +9,7 @@ from discord.ext.commands import Bot, Context, group
from bot.cogs.modlog import ModLog
from bot.constants import (
Channels, CleanMessages, Colours, Event,
- Icons, NEGATIVE_REPLIES, Roles
+ Icons, MODERATION_ROLES, NEGATIVE_REPLIES
)
from bot.decorators import with_role
@@ -190,7 +190,7 @@ class Clean:
)
@group(invoke_without_command=True, name="clean", hidden=True)
- @with_role(Roles.moderator, Roles.admin, Roles.owner)
+ @with_role(*MODERATION_ROLES)
async def clean_group(self, ctx: Context):
"""
Commands for cleaning messages in channels
@@ -199,7 +199,7 @@ class Clean:
await ctx.invoke(self.bot.get_command("help"), "clean")
@clean_group.command(name="user", aliases=["users"])
- @with_role(Roles.moderator, Roles.admin, Roles.owner)
+ @with_role(*MODERATION_ROLES)
async def clean_user(self, ctx: Context, user: User, amount: int = 10):
"""
Delete messages posted by the provided user,
@@ -209,7 +209,7 @@ class Clean:
await self._clean_messages(amount, ctx, user=user)
@clean_group.command(name="all", aliases=["everything"])
- @with_role(Roles.moderator, Roles.admin, Roles.owner)
+ @with_role(*MODERATION_ROLES)
async def clean_all(self, ctx: Context, amount: int = 10):
"""
Delete all messages, regardless of poster,
@@ -219,7 +219,7 @@ class Clean:
await self._clean_messages(amount, ctx)
@clean_group.command(name="bots", aliases=["bot"])
- @with_role(Roles.moderator, Roles.admin, Roles.owner)
+ @with_role(*MODERATION_ROLES)
async def clean_bots(self, ctx: Context, amount: int = 10):
"""
Delete all messages posted by a bot,
@@ -229,7 +229,7 @@ class Clean:
await self._clean_messages(amount, ctx, bots_only=True)
@clean_group.command(name="regex", aliases=["word", "expression"])
- @with_role(Roles.moderator, Roles.admin, Roles.owner)
+ @with_role(*MODERATION_ROLES)
async def clean_regex(self, ctx: Context, regex, amount: int = 10):
"""
Delete all messages that match a certain regex,
@@ -239,7 +239,7 @@ class Clean:
await self._clean_messages(amount, ctx, regex=regex)
@clean_group.command(name="stop", aliases=["cancel", "abort"])
- @with_role(Roles.moderator, Roles.admin, Roles.owner)
+ @with_role(*MODERATION_ROLES)
async def clean_cancel(self, ctx: Context):
"""
If there is an ongoing cleaning process,
diff --git a/bot/cogs/cogs.py b/bot/cogs/cogs.py
index 0a33b3de0..11b64851a 100644
--- a/bot/cogs/cogs.py
+++ b/bot/cogs/cogs.py
@@ -5,7 +5,7 @@ from discord import Colour, Embed
from discord.ext.commands import Bot, Context, group
from bot.constants import (
- Emojis, Roles, URLs,
+ Emojis, MODERATION_ROLES, Roles, URLs
)
from bot.decorators import with_role
from bot.pagination import LinePaginator
@@ -37,14 +37,14 @@ class Cogs:
self.cogs.update({v: k for k, v in self.cogs.items()})
@group(name='cogs', aliases=('c',), invoke_without_command=True)
- @with_role(Roles.moderator, Roles.admin, Roles.owner, Roles.devops)
+ @with_role(*MODERATION_ROLES, Roles.devops)
async def cogs_group(self, ctx: Context):
"""Load, unload, reload, and list active cogs."""
await ctx.invoke(self.bot.get_command("help"), "cogs")
@cogs_group.command(name='load', aliases=('l',))
- @with_role(Roles.moderator, Roles.admin, Roles.owner, Roles.devops)
+ @with_role(*MODERATION_ROLES, Roles.devops)
async def load_command(self, ctx: Context, cog: str):
"""
Load up an unloaded cog, given the module containing it
@@ -97,7 +97,7 @@ class Cogs:
await ctx.send(embed=embed)
@cogs_group.command(name='unload', aliases=('ul',))
- @with_role(Roles.moderator, Roles.admin, Roles.owner, Roles.devops)
+ @with_role(*MODERATION_ROLES, Roles.devops)
async def unload_command(self, ctx: Context, cog: str):
"""
Unload an already-loaded cog, given the module containing it
@@ -149,7 +149,7 @@ class Cogs:
await ctx.send(embed=embed)
@cogs_group.command(name='reload', aliases=('r',))
- @with_role(Roles.moderator, Roles.admin, Roles.owner, Roles.devops)
+ @with_role(*MODERATION_ROLES, Roles.devops)
async def reload_command(self, ctx: Context, cog: str):
"""
Reload an unloaded cog, given the module containing it
@@ -254,7 +254,7 @@ class Cogs:
await ctx.send(embed=embed)
@cogs_group.command(name='list', aliases=('all',))
- @with_role(Roles.moderator, Roles.admin, Roles.owner, Roles.devops)
+ @with_role(*MODERATION_ROLES, Roles.devops)
async def list_command(self, ctx: Context):
"""
Get a list of all cogs, including their loaded status.
diff --git a/bot/cogs/deployment.py b/bot/cogs/deployment.py
index bc9dbf5ab..e71e07c2f 100644
--- a/bot/cogs/deployment.py
+++ b/bot/cogs/deployment.py
@@ -3,7 +3,7 @@ import logging
from discord import Colour, Embed
from discord.ext.commands import Bot, Context, command, group
-from bot.constants import Keys, Roles, URLs
+from bot.constants import Keys, MODERATION_ROLES, Roles, URLs
from bot.decorators import with_role
log = logging.getLogger(__name__)
@@ -18,7 +18,7 @@ class Deployment:
self.bot = bot
@group(name='redeploy', invoke_without_command=True)
- @with_role(Roles.owner, Roles.admin, Roles.moderator)
+ @with_role(*MODERATION_ROLES)
async def redeploy_group(self, ctx: Context):
"""Redeploy the bot or the site."""
diff --git a/bot/cogs/doc.py b/bot/cogs/doc.py
index 2b310f11c..2f2cf8000 100644
--- a/bot/cogs/doc.py
+++ b/bot/cogs/doc.py
@@ -14,7 +14,7 @@ from markdownify import MarkdownConverter
from requests import ConnectionError
from sphinx.ext import intersphinx
-from bot.constants import ERROR_REPLIES, Keys, Roles, URLs
+from bot.constants import ERROR_REPLIES, Keys, MODERATION_ROLES, URLs
from bot.converters import ValidPythonIdentifier, ValidURL
from bot.decorators import with_role
from bot.pagination import LinePaginator
@@ -405,7 +405,7 @@ class Doc:
await ctx.send(embed=doc_embed)
@docs_group.command(name='set', aliases=('s',))
- @with_role(Roles.admin, Roles.owner, Roles.moderator)
+ @with_role(*MODERATION_ROLES)
async def set_command(
self, ctx, package_name: ValidPythonIdentifier,
base_url: ValidURL, inventory_url: InventoryURL
@@ -443,7 +443,7 @@ class Doc:
await ctx.send(f"Added package `{package_name}` to database and refreshed inventory.")
@docs_group.command(name='delete', aliases=('remove', 'rm', 'd'))
- @with_role(Roles.admin, Roles.owner, Roles.moderator)
+ @with_role(*MODERATION_ROLES)
async def delete_command(self, ctx, package_name: ValidPythonIdentifier):
"""
Removes the specified package from the database.
diff --git a/bot/cogs/information.py b/bot/cogs/information.py
index 0d31cb0d3..469999c00 100644
--- a/bot/cogs/information.py
+++ b/bot/cogs/information.py
@@ -5,15 +5,16 @@ import textwrap
from discord import CategoryChannel, Colour, Embed, Member, TextChannel, VoiceChannel
from discord.ext.commands import BadArgument, Bot, CommandError, Context, MissingPermissions, command
-from bot.constants import Channels, Emojis, Keys, NEGATIVE_REPLIES, Roles, URLs
+from bot.constants import (
+ Channels, Emojis, Keys, MODERATION_ROLES,
+ NEGATIVE_REPLIES, STAFF_ROLES, URLs
+)
from bot.decorators import with_role
from bot.utils.checks import with_role_check
from bot.utils.time import time_since
log = logging.getLogger(__name__)
-MODERATION_ROLES = Roles.owner, Roles.admin, Roles.moderator
-
class Information:
"""
@@ -137,7 +138,7 @@ class Information:
# Non-moderators may only do this in #bot-commands and can't see
# hidden infractions.
- if not with_role_check(ctx, *MODERATION_ROLES):
+ if not with_role_check(ctx, *STAFF_ROLES):
if not ctx.channel.id == Channels.bot:
raise MissingPermissions("You can't do that here!")
# Hide hidden infractions for users without a moderation role
diff --git a/bot/cogs/moderation.py b/bot/cogs/moderation.py
index 3c7f80a7a..5d8aa0217 100644
--- a/bot/cogs/moderation.py
+++ b/bot/cogs/moderation.py
@@ -13,7 +13,7 @@ from discord.ext.commands import (
from bot import constants
from bot.cogs.modlog import ModLog
-from bot.constants import Colours, Event, Icons, Keys, Roles, URLs
+from bot.constants import Colours, Event, Icons, Keys, MODERATION_ROLES, URLs
from bot.converters import InfractionSearchQuery
from bot.decorators import with_role
from bot.pagination import LinePaginator
@@ -23,7 +23,6 @@ from bot.utils.time import parse_rfc1123, wait_until
log = logging.getLogger(__name__)
-MODERATION_ROLES = Roles.owner, Roles.admin, Roles.moderator
INFRACTION_ICONS = {
"Mute": Icons.user_mute,
"Kick": Icons.sign_out,
diff --git a/bot/cogs/snekbox.py b/bot/cogs/snekbox.py
index cfbd032cb..1cef3986d 100644
--- a/bot/cogs/snekbox.py
+++ b/bot/cogs/snekbox.py
@@ -10,7 +10,7 @@ from discord.ext.commands import (
)
from bot.cogs.rmq import RMQ
-from bot.constants import Channels, ERROR_REPLIES, NEGATIVE_REPLIES, Roles, URLs
+from bot.constants import Channels, ERROR_REPLIES, NEGATIVE_REPLIES, STAFF_ROLES, URLs
from bot.decorators import InChannelCheckFailure, in_channel
from bot.utils.messages import wait_for_deletion
@@ -53,8 +53,6 @@ RAW_CODE_REGEX = re.compile(
re.DOTALL # "." also matches newlines
)
-BYPASS_ROLES = (Roles.owner, Roles.admin, Roles.moderator, Roles.helpers)
-
class Snekbox:
"""
@@ -71,7 +69,7 @@ class Snekbox:
@command(name='eval', aliases=('e',))
@guild_only()
- @in_channel(Channels.bot, bypass_roles=BYPASS_ROLES)
+ @in_channel(Channels.bot, bypass_roles=STAFF_ROLES)
async def eval_command(self, ctx: Context, *, code: str = None):
"""
Run some code. get the result back. We've done our best to make this safe, but do let us know if you
diff --git a/bot/cogs/superstarify.py b/bot/cogs/superstarify.py
index 84467bd8c..f46f62552 100644
--- a/bot/cogs/superstarify.py
+++ b/bot/cogs/superstarify.py
@@ -9,8 +9,8 @@ from bot.cogs.moderation import Moderation
from bot.cogs.modlog import ModLog
from bot.constants import (
Icons, Keys,
- NEGATIVE_REPLIES, POSITIVE_REPLIES,
- Roles, URLs
+ MODERATION_ROLES, NEGATIVE_REPLIES,
+ POSITIVE_REPLIES, URLs
)
from bot.decorators import with_role
@@ -143,7 +143,7 @@ class Superstarify:
)
@command(name='superstarify', aliases=('force_nick', 'star'))
- @with_role(Roles.admin, Roles.owner, Roles.moderator)
+ @with_role(*MODERATION_ROLES)
async def superstarify(self, ctx: Context, member: Member, duration: str, *, forced_nick: str = None):
"""
This command will force a random superstar name (like Taylor Swift) to be the user's
@@ -235,7 +235,7 @@ class Superstarify:
await ctx.send(embed=embed)
@command(name='unsuperstarify', aliases=('release_nick', 'unstar'))
- @with_role(Roles.admin, Roles.owner, Roles.moderator)
+ @with_role(*MODERATION_ROLES)
async def unsuperstarify(self, ctx: Context, member: Member):
"""
This command will remove the entry from our database, allowing the user
diff --git a/bot/cogs/tags.py b/bot/cogs/tags.py
index 8ecd80127..d6957e360 100644
--- a/bot/cogs/tags.py
+++ b/bot/cogs/tags.py
@@ -10,7 +10,8 @@ from discord.ext.commands import (
)
from bot.constants import (
- Channels, Cooldowns, ERROR_REPLIES, Keys, Roles, URLs
+ Channels, Cooldowns, ERROR_REPLIES, Keys,
+ MODERATION_ROLES, Roles, URLs
)
from bot.converters import TagContentConverter, TagNameConverter, ValidURL
from bot.decorators import with_role
@@ -212,7 +213,7 @@ class Tags:
return await ctx.send(embed=embed)
@tags_group.command(name='set', aliases=('add', 'edit', 's'))
- @with_role(Roles.admin, Roles.owner, Roles.moderator)
+ @with_role(*MODERATION_ROLES)
async def set_command(
self,
ctx: Context,
diff --git a/bot/cogs/utils.py b/bot/cogs/utils.py
index 65c729414..0c6d9d2ba 100644
--- a/bot/cogs/utils.py
+++ b/bot/cogs/utils.py
@@ -8,13 +8,11 @@ from io import StringIO
from discord import Colour, Embed
from discord.ext.commands import AutoShardedBot, Context, command
-from bot.constants import Channels, NEGATIVE_REPLIES, Roles
+from bot.constants import Channels, NEGATIVE_REPLIES, STAFF_ROLES
from bot.decorators import InChannelCheckFailure, in_channel
log = logging.getLogger(__name__)
-BYPASS_ROLES = (Roles.owner, Roles.admin, Roles.moderator, Roles.helpers)
-
class Utils:
"""
@@ -91,7 +89,7 @@ class Utils:
await ctx.message.channel.send(embed=pep_embed)
@command()
- @in_channel(Channels.bot, bypass_roles=BYPASS_ROLES)
+ @in_channel(Channels.bot, bypass_roles=STAFF_ROLES)
async def charinfo(self, ctx, *, characters: str):
"""
Shows you information on up to 25 unicode characters.
diff --git a/bot/cogs/wolfram.py b/bot/cogs/wolfram.py
index c36ef6075..f16c28dde 100644
--- a/bot/cogs/wolfram.py
+++ b/bot/cogs/wolfram.py
@@ -8,7 +8,7 @@ from discord import Embed
from discord.ext import commands
from discord.ext.commands import BucketType, Context, check, group
-from bot.constants import Colours, Roles, Wolfram
+from bot.constants import Colours, STAFF_ROLES, Wolfram
from bot.pagination import ImagePaginator
log = logging.getLogger(__name__)
@@ -18,7 +18,6 @@ DEFAULT_OUTPUT_FORMAT = "JSON"
QUERY = "http://api.wolframalpha.com/v2/{request}?{data}"
WOLF_IMAGE = "https://www.symbols.com/gi.php?type=1&id=2886&i=1"
-COOLDOWN_IGNORERS = Roles.moderator, Roles.owner, Roles.admin, Roles.helpers
MAX_PODS = 20
# Allows for 10 wolfram calls pr user pr day
@@ -159,7 +158,7 @@ class Wolfram:
self.bot = bot
@group(name="wolfram", aliases=("wolf", "wa"), invoke_without_command=True)
- @custom_cooldown(*COOLDOWN_IGNORERS)
+ @custom_cooldown(*STAFF_ROLES)
async def wolfram_command(self, ctx: Context, *, query: str) -> None:
"""
Requests all answers on a single image,
@@ -201,7 +200,7 @@ class Wolfram:
await send_embed(ctx, message, color, footer=footer, img_url=image_url, f=f)
@wolfram_command.command(name="page", aliases=("pa", "p"))
- @custom_cooldown(*COOLDOWN_IGNORERS)
+ @custom_cooldown(*STAFF_ROLES)
async def wolfram_page_command(self, ctx: Context, *, query: str) -> None:
"""
Requests a drawn image of given query
@@ -225,7 +224,7 @@ class Wolfram:
await ImagePaginator.paginate(pages, ctx, embed)
@wolfram_command.command(name="cut", aliases=("c",))
- @custom_cooldown(*COOLDOWN_IGNORERS)
+ @custom_cooldown(*STAFF_ROLES)
async def wolfram_cut_command(self, ctx, *, query: str) -> None:
"""
Requests a drawn image of given query
@@ -248,7 +247,7 @@ class Wolfram:
await send_embed(ctx, page[0], colour=Colours.soft_orange, img_url=page[1])
@wolfram_command.command(name="short", aliases=("sh", "s"))
- @custom_cooldown(*COOLDOWN_IGNORERS)
+ @custom_cooldown(*STAFF_ROLES)
async def wolfram_short_command(self, ctx: Context, *, query: str) -> None:
"""
Requests an answer to a simple question
diff --git a/bot/constants.py b/bot/constants.py
index 5b9b45c1c..99afc1e6e 100644
--- a/bot/constants.py
+++ b/bot/constants.py
@@ -498,8 +498,10 @@ BOT_DIR = os.path.dirname(__file__)
PROJECT_ROOT = os.path.abspath(os.path.join(BOT_DIR, os.pardir))
# Default role combinations
+MODERATION_ROLES = Roles.moderator, Roles.admin, Roles.owner
STAFF_ROLES = Roles.helpers, Roles.moderator, Roles.admin, Roles.owner
+
# Bot replies
NEGATIVE_REPLIES = [
"Noooooo!!",