From 0b8483511bdde27b6b2ceadfda770b3b8b15dba2 Mon Sep 17 00:00:00 2001 From: Valerie Date: Sun, 25 May 2025 04:29:13 -0400 Subject: [PATCH] Refactor RubyAPI cog to support global configuration. Update commands to manage API key, interaction URL, and verification URL globally instead of per guild. Implement cog-wide checks to restrict command usage to bot team members only, enhancing security and usability. --- rubyapi/rubyapi.py | 78 +++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 42 deletions(-) diff --git a/rubyapi/rubyapi.py b/rubyapi/rubyapi.py index 6a493d1..2300435 100644 --- a/rubyapi/rubyapi.py +++ b/rubyapi/rubyapi.py @@ -1,7 +1,7 @@ from typing import Optional import aiohttp import discord -from redbot.core import commands, Config +from redbot.core import commands, Config, checks from redbot.core.bot import Red from redbot.core.utils.chat_formatting import box @@ -14,37 +14,40 @@ class RubyAPI(commands.Cog): self.config = Config.get_conf(self, identifier=867530999, force_registration=True) self.session = aiohttp.ClientSession() - default_guild = { - "interaction_url": "https://ruby.valerie.lol/api/interactions", - "verify_url": "https://ruby.valerie.lol/verify-user", - "enabled": False, + default_global = { + "interaction_url": "https://ruby.valerie.lol/api/verify-user", # Default interaction URL + "verify_url": "https://ruby.valerie.lol/api/verify-user", # Default verify URL + "enabled": True, # Enabled by default "api_key": None } - self.config.register_guild(**default_guild) + self.config.register_global(**default_global) def cog_unload(self): if self.session: self.bot.loop.create_task(self.session.close()) + async def cog_check(self, ctx: commands.Context) -> bool: + """Cog-wide check to ensure only bot team members can use commands.""" + return await self.bot.is_owner(ctx.author) or await self.bot.is_co_owner(ctx.author) + @commands.group(name="rubyapi") - @commands.admin_or_permissions(manage_guild=True) async def rubyapi(self, ctx: commands.Context): - """Ruby API configuration commands.""" + """Ruby API configuration commands. Bot team only.""" pass @rubyapi.command(name="enable") async def enable_integration(self, ctx: commands.Context, toggle: bool): - """Enable or disable Ruby API integration.""" - await self.config.guild(ctx.guild).enabled.set(toggle) + """Enable or disable Ruby API integration globally.""" + await self.config.enabled.set(toggle) status = "enabled" if toggle else "disabled" - await ctx.send(f"Ruby API integration has been {status}.") + await ctx.send(f"Ruby API integration has been {status} globally.") @rubyapi.command(name="setkey") async def set_api_key(self, ctx: commands.Context, api_key: str): """Set the API key for authentication.""" - await self.config.guild(ctx.guild).api_key.set(api_key) - await ctx.send("API key has been set. I'll delete your message for security.") + await self.config.api_key.set(api_key) + await ctx.send("API key has been set globally. I'll delete your message for security.") try: await ctx.message.delete() except discord.HTTPException: @@ -56,8 +59,8 @@ class RubyAPI(commands.Cog): if not url.startswith(("http://", "https://")): return await ctx.send("Please provide a valid URL starting with http:// or https://") - await self.config.guild(ctx.guild).interaction_url.set(url) - await ctx.send("Interaction endpoint URL has been updated.") + await self.config.interaction_url.set(url) + await ctx.send("Interaction endpoint URL has been updated globally.") @rubyapi.command(name="setverify") async def set_verify_url(self, ctx: commands.Context, url: str): @@ -65,21 +68,21 @@ class RubyAPI(commands.Cog): if not url.startswith(("http://", "https://")): return await ctx.send("Please provide a valid URL starting with http:// or https://") - await self.config.guild(ctx.guild).verify_url.set(url) - await ctx.send("Verification endpoint URL has been updated.") + await self.config.verify_url.set(url) + await ctx.send("Verification endpoint URL has been updated globally.") @rubyapi.command(name="settings") async def show_settings(self, ctx: commands.Context): """Show current Ruby API settings.""" - guild_config = await self.config.guild(ctx.guild).all() + config = await self.config.all() - enabled = "Yes" if guild_config["enabled"] else "No" - interaction_url = guild_config["interaction_url"] - verify_url = guild_config["verify_url"] - has_api_key = "Yes" if guild_config["api_key"] else "No" + enabled = "Yes" if config["enabled"] else "No" + interaction_url = config["interaction_url"] + verify_url = config["verify_url"] + has_api_key = "Yes" if config["api_key"] else "No" message = ( - "Ruby API Settings:\n" + "Ruby API Global Settings:\n" f"Enabled: {enabled}\n" f"API Key Set: {has_api_key}\n" f"Interaction URL: {interaction_url}\n" @@ -91,7 +94,7 @@ class RubyAPI(commands.Cog): async def _make_api_request(self, url: str, method: str = "GET", **kwargs): """Make an API request with proper headers and error handling.""" headers = kwargs.pop("headers", {}) - if api_key := kwargs.pop("api_key", None): + if api_key := await self.config.api_key(): headers["Authorization"] = f"Bearer {api_key}" try: @@ -107,13 +110,13 @@ class RubyAPI(commands.Cog): @commands.command() async def verifyuser(self, ctx: commands.Context, user: Optional[discord.Member] = None): - """Verify a user's linked roles.""" - if not await self.config.guild(ctx.guild).enabled(): - return await ctx.send("Ruby API integration is not enabled in this server.") + """Verify a user's linked roles. Bot team only.""" + if not await self.config.enabled(): + return await ctx.send("Ruby API integration is not enabled globally.") user = user or ctx.author - verify_url = await self.config.guild(ctx.guild).verify_url() - api_key = await self.config.guild(ctx.guild).api_key() + verify_url = await self.config.verify_url() + api_key = await self.config.api_key() if not api_key: return await ctx.send("API key has not been set. Please set it using `[p]rubyapi setkey`") @@ -127,8 +130,7 @@ class RubyAPI(commands.Cog): result = await self._make_api_request( verify_url, method="POST", - json=payload, - api_key=api_key + json=payload ) if "error" in result: @@ -155,17 +157,10 @@ class RubyAPI(commands.Cog): @commands.Cog.listener() async def on_interaction(self, interaction: discord.Interaction): """Handle incoming Discord interactions.""" - if not interaction.guild: - return - - if not await self.config.guild(interaction.guild).enabled(): + if not await self.config.enabled(): return - interaction_url = await self.config.guild(interaction.guild).interaction_url() - api_key = await self.config.guild(interaction.guild).api_key() - - if not api_key: - return # Silent return if API key is not set + interaction_url = await self.config.interaction_url() # Forward the interaction to the API payload = { @@ -186,8 +181,7 @@ class RubyAPI(commands.Cog): result = await self._make_api_request( interaction_url, method="POST", - json=payload, - api_key=api_key + json=payload ) # Handle the API response if needed