Begin work on a data request API (#4045)

[Core] Data Deletion And Disclosure APIs

 - Adds a Data Deletion API
   - Deletion comes in a few forms based on who is requesting
   - Deletion must be handled by 3rd party
 - Adds a Data Collection Disclosure Command
   - Provides a dynamically generated statement from 3rd party
   extensions
 - Modifies the always available commands to be cog compatible
   - Also prevents them from being unloaded accidentally
This commit is contained in:
Michael H
2020-08-03 09:09:07 -04:00
committed by GitHub
parent bb1a256295
commit c0b1e50a5f
38 changed files with 1761 additions and 222 deletions

View File

@@ -1,7 +1,8 @@
import asyncio
import contextlib
from collections import namedtuple
from copy import copy
from typing import Union, Optional
from typing import Union, Optional, Literal
import discord
@@ -14,6 +15,7 @@ from redbot.cogs.warnings.helpers import (
from redbot.core import Config, checks, commands, modlog
from redbot.core.bot import Red
from redbot.core.i18n import Translator, cog_i18n
from redbot.core.utils import AsyncIter
from redbot.core.utils.chat_formatting import warning, pagify
from redbot.core.utils.menus import menu, DEFAULT_CONTROLS
@@ -45,6 +47,41 @@ class Warnings(commands.Cog):
self.bot = bot
self.registration_task = self.bot.loop.create_task(self.register_warningtype())
async def red_delete_data_for_user(
self,
*,
requester: Literal["discord_deleted_user", "owner", "user", "user_strict"],
user_id: int,
):
if requester != "discord_deleted_user":
return
all_members = await self.config.all_members()
c = 0
for guild_id, guild_data in all_members.items():
c += 1
if not c % 100:
await asyncio.sleep(0)
if user_id in guild_data:
await self.config.member_from_ids(guild_id, user_id).clear()
for remaining_user, user_warns in guild_data.items():
c += 1
if not c % 100:
await asyncio.sleep(0)
for warn_id, warning in user_warns.get("warnings", {}).items():
c += 1
if not c % 100:
await asyncio.sleep(0)
if warning.get("mod", 0) == user_id:
grp = self.config.member_from_ids(guild_id, remaining_user)
await grp.set_raw("warnings", warn_id, "mod", value=0xDE1)
# We're not utilising modlog yet - no need to register a casetype
@staticmethod
async def register_warningtype():
@@ -489,7 +526,11 @@ class Warnings(commands.Cog):
else:
for key in user_warnings.keys():
mod_id = user_warnings[key]["mod"]
mod = ctx.bot.get_user(mod_id) or _("Unknown Moderator ({})").format(mod_id)
if mod_id == 0xDE1:
mod = _("Deleted Moderator")
else:
bot = ctx.bot
mod = bot.get_user(mod_id) or _("Unknown Moderator ({})").format(mod_id)
msg += _(
"{num_points} point warning {reason_name} issued by {user} for "
"{description}\n"
@@ -519,7 +560,11 @@ class Warnings(commands.Cog):
else:
for key in user_warnings.keys():
mod_id = user_warnings[key]["mod"]
mod = ctx.bot.get_user(mod_id) or _("Unknown Moderator ({})").format(mod_id)
if mod_id == 0xDE1:
mod = _("Deleted Moderator")
else:
bot = ctx.bot
mod = bot.get_user(mod_id) or _("Unknown Moderator ({})").format(mod_id)
msg += _(
"{num_points} point warning {reason_name} issued by {user} for "
"{description}\n"