Updated the consent to allow opt-in or out

This commit is contained in:
Dan
2024-05-04 21:46:10 -04:00
parent c7791fc4aa
commit f0da9a3241
3 changed files with 40 additions and 10 deletions

View File

@ -1,6 +1,7 @@
import discord import discord
from discord import app_commands from discord import app_commands
from .database import add_project, get_project_id, get_project_name, add_task_to_project, update_task, list_projects, list_tasks_for_project, remove_task, remove_project from .database import add_project, get_project_id, get_project_name, add_task_to_project, update_task, list_projects, list_tasks_for_project, remove_task, remove_project
from .consent import check_user_consent, store_user_consent, revoke_user_consent
from datetime import datetime from datetime import datetime
import logging import logging
@ -108,8 +109,23 @@ class TaskCommands(app_commands.Group):
await interaction.response.send_message("Failed to remove the task.", ephemeral=True) await interaction.response.send_message("Failed to remove the task.", ephemeral=True)
logger.error(f"Error in remove_task_command: {e}") logger.error(f"Error in remove_task_command: {e}")
class ConsentCommands(app_commands.Group):
def __init__(self):
super().__init__(name="consent", description="Manage data consent settings.")
@app_commands.command(name="opt-in", description="Opt-in to data storage and use the bot.")
async def opt_in(self, interaction: discord.Interaction):
await store_user_consent(interaction.user.id)
await interaction.response.send_message("You have opted in to data storage. You can now use the bot.", ephemeral=True)
@app_commands.command(name="opt-out", description="Opt-out of data storage and stop using the bot.")
async def opt_out(self, interaction: discord.Interaction):
await revoke_user_consent(interaction.user.id)
await interaction.response.send_message("You have opted out of data storage. You will no longer be able to use the bot.", ephemeral=True)
class DollyTracker(app_commands.Group, name="dolly", description="Dolly the Project Tracker."): class DollyTracker(app_commands.Group, name="dolly", description="Dolly the Project Tracker."):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.add_command(ProjectCommands()) self.add_command(ProjectCommands())
self.add_command(TaskCommands()) self.add_command(TaskCommands())
self.add_command(ConsentCommands())

View File

@ -12,22 +12,27 @@ class ConsentView(View):
@discord.ui.button(label="Consent to Data Storage", style=discord.ButtonStyle.green) @discord.ui.button(label="Consent to Data Storage", style=discord.ButtonStyle.green)
async def confirm(self, interaction: discord.Interaction, button: Button): async def confirm(self, interaction: discord.Interaction, button: Button):
self.value = True self.value = True
await interaction.response.send_message("Thank you for consenting to data storage!", ephemeral=True) await store_user_consent(interaction.user.id)
await interaction.response.edit_message(content="Thank you for consenting to data storage!", view=None)
self.stop() self.stop()
@discord.ui.button(label="Decline", style=discord.ButtonStyle.grey) @discord.ui.button(label="Decline Data Storage", style=discord.ButtonStyle.grey)
async def cancel(self, interaction: discord.Interaction, button: Button): async def cancel(self, interaction: discord.Interaction, button: Button):
self.value = False self.value = False
await interaction.response.send_message("You have declined data storage. You cannot use this bot without consenting.", ephemeral=True) await interaction.response.edit_message(content="You have declined data storage. You cannot use this bot without consenting.", view=None)
self.stop() self.stop()
async def check_user_consent(user_id): async def check_user_consent(user_id):
"""Check if the user has given consent to data storage.""" """Check if the user has given consent to data storage, default to True."""
async with aiosqlite.connect(DATABASE) as db: async with aiosqlite.connect(DATABASE) as db:
cursor = await db.execute("SELECT consent_given FROM user_consents WHERE user_id = ?", (user_id,)) cursor = await db.execute("SELECT consent_given FROM user_consents WHERE user_id = ?", (user_id,))
result = await cursor.fetchone() result = await cursor.fetchone()
return result[0] if result else False if result is None:
# Assume consent given if no record exists
return True
return result[0]
async def store_user_consent(user_id): async def store_user_consent(user_id):
"""Store the user's consent to data storage.""" """Store the user's consent to data storage."""
@ -35,3 +40,8 @@ async def store_user_consent(user_id):
await db.execute("INSERT OR REPLACE INTO user_consents (user_id, consent_given) VALUES (?, TRUE)", (user_id,)) await db.execute("INSERT OR REPLACE INTO user_consents (user_id, consent_given) VALUES (?, TRUE)", (user_id,))
await db.commit() await db.commit()
async def revoke_user_consent(user_id):
"""Revoke the user's consent to data storage."""
async with aiosqlite.connect(DATABASE) as db:
await db.execute("UPDATE user_consents SET consent_given = FALSE WHERE user_id = ?", (user_id,))
await db.commit()

View File

@ -33,7 +33,13 @@ class Dolly(discord.Client):
async def on_interaction(self, interaction: discord.Interaction): async def on_interaction(self, interaction: discord.Interaction):
if interaction.type == discord.InteractionType.application_command: if interaction.type == discord.InteractionType.application_command:
# Check if the command is about managing consent, which should be allowed regardless
if interaction.command.name in ['opt-in', 'opt-out']:
return # Let these commands process normally
# Check user consent
if not await check_user_consent(interaction.user.id): if not await check_user_consent(interaction.user.id):
# Present the consent view if no consent is recorded
view = ConsentView() view = ConsentView()
await interaction.response.send_message( await interaction.response.send_message(
"By using this bot, you consent to the storage of your data necessary for functionality. Please confirm your consent.", "By using this bot, you consent to the storage of your data necessary for functionality. Please confirm your consent.",
@ -41,9 +47,7 @@ class Dolly(discord.Client):
ephemeral=True ephemeral=True
) )
await view.wait() await view.wait()
if view.value: if not view.value:
await store_user_consent(interaction.user.id) # If after the view they still haven't consented, halt further processing
else:
# Optionally, handle the case where the user declines consent
await interaction.followup.send("You must consent to data storage to use this bot.", ephemeral=True) await interaction.followup.send("You must consent to data storage to use this bot.", ephemeral=True)
return # Stop processing if they do not consent return # Stop processing if they do not consent