From 1484f6b9a7abd705fe301b35b32a149091a76533 Mon Sep 17 00:00:00 2001
From: Dragory <2606411+Dragory@users.noreply.github.com>
Date: Wed, 23 Dec 2020 04:44:43 +0200
Subject: [PATCH] mod_actions: add create_cases_for_manual_actions option

This can also be used with a user override.
The override user is the audit log entry's author, i.e. the user who
did the kick/ban/unban.
---
 .../plugins/ModActions/ModActionsPlugin.ts    |  1 +
 .../events/CreateBanCaseOnManualBanEvt.ts     | 42 ++++++++++-------
 .../events/CreateKickCaseOnManualKickEvt.ts   | 46 +++++++++++--------
 .../events/CreateUnbanCaseOnManualUnbanEvt.ts | 40 +++++++++-------
 backend/src/plugins/ModActions/types.ts       |  1 +
 5 files changed, 79 insertions(+), 51 deletions(-)

diff --git a/backend/src/plugins/ModActions/ModActionsPlugin.ts b/backend/src/plugins/ModActions/ModActionsPlugin.ts
index a43a7d1a..e091b038 100644
--- a/backend/src/plugins/ModActions/ModActionsPlugin.ts
+++ b/backend/src/plugins/ModActions/ModActionsPlugin.ts
@@ -69,6 +69,7 @@ const defaultOptions = {
     can_hidecase: false,
     can_deletecase: false,
     can_act_as_other: false,
+    create_cases_for_manual_actions: true,
   },
   overrides: [
     {
diff --git a/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts b/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts
index a899c34c..931b7985 100644
--- a/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts
+++ b/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts
@@ -7,6 +7,7 @@ import { CaseTypes } from "../../../data/CaseTypes";
 import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry";
 import { LogType } from "../../../data/LogType";
 import { stripObjectToScalars, resolveUser, UnknownUser } from "../../../utils";
+import { Case } from "../../../data/entities/Case";
 
 /**
  * Create a BAN case automatically when a user is banned manually.
@@ -28,7 +29,7 @@ export const CreateBanCaseOnManualBanEvt = modActionsEvt(
 
     const casesPlugin = pluginData.getPlugin(CasesPlugin);
 
-    let createdCase;
+    let createdCase: Case | null = null;
     let mod: User | UnknownUser | null = null;
     let reason = "";
 
@@ -37,28 +38,35 @@ export const CreateBanCaseOnManualBanEvt = modActionsEvt(
       const auditLogId = relevantAuditLogEntry.id;
 
       mod = await resolveUser(pluginData.client, modId);
-      reason = relevantAuditLogEntry.reason || "";
-      createdCase = await casesPlugin.createCase({
-        userId: user.id,
-        modId,
-        type: CaseTypes.Ban,
-        auditLogId,
-        reason: reason || undefined,
-        automatic: true,
-      });
+
+      const config = mod instanceof UnknownUser ? pluginData.config.get() : pluginData.config.getForUser(mod);
+
+      if (config.create_cases_for_manual_actions) {
+        reason = relevantAuditLogEntry.reason || "";
+        createdCase = await casesPlugin.createCase({
+          userId: user.id,
+          modId,
+          type: CaseTypes.Ban,
+          auditLogId,
+          reason: reason || undefined,
+          automatic: true,
+        });
+      }
     } else {
-      createdCase = await casesPlugin.createCase({
-        userId: user.id,
-        modId: "0",
-        type: CaseTypes.Ban,
-      });
+      const config = pluginData.config.get();
+      if (config.create_cases_for_manual_actions) {
+        createdCase = await casesPlugin.createCase({
+          userId: user.id,
+          modId: "0",
+          type: CaseTypes.Ban,
+        });
+      }
     }
 
-    mod = await mod;
     pluginData.state.serverLogs.log(LogType.MEMBER_BAN, {
       mod: mod ? stripObjectToScalars(mod, ["user"]) : null,
       user: stripObjectToScalars(user, ["user"]),
-      caseNumber: createdCase.case_number,
+      caseNumber: createdCase?.case_number ?? 0,
       reason,
     });
   },
diff --git a/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts b/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts
index e97c6106..b461f3aa 100644
--- a/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts
+++ b/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts
@@ -1,13 +1,14 @@
 import { IgnoredEventType, modActionsEvt } from "../types";
 import { isEventIgnored } from "../functions/isEventIgnored";
 import { clearIgnoredEvents } from "../functions/clearIgnoredEvents";
-import { Constants as ErisConstants } from "eris";
+import { Constants as ErisConstants, User } from "eris";
 import { CasesPlugin } from "../../Cases/CasesPlugin";
 import { CaseTypes } from "../../../data/CaseTypes";
 import { logger } from "../../../logger";
 import { LogType } from "../../../data/LogType";
-import { stripObjectToScalars } from "../../../utils";
+import { resolveUser, stripObjectToScalars, UnknownUser } from "../../../utils";
 import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry";
+import { Case } from "../../../data/entities/Case";
 
 /**
  * Create a KICK case automatically when a user is kicked manually.
@@ -27,29 +28,38 @@ export const CreateKickCaseOnManualKickEvt = modActionsEvt(
       member.id,
     );
 
+    let mod: User | UnknownUser | null = null;
+    let createdCase: Case | null = null;
+
     if (kickAuditLogEntry) {
-      let createdCase = await pluginData.state.cases.findByAuditLogId(kickAuditLogEntry.id);
+      createdCase = (await pluginData.state.cases.findByAuditLogId(kickAuditLogEntry.id)) || null;
       if (createdCase) {
         logger.warn(
           `Tried to create duplicate case for audit log entry ${kickAuditLogEntry.id}, existing case id ${createdCase.id}`,
         );
       } else {
-        const casesPlugin = pluginData.getPlugin(CasesPlugin);
-        createdCase = await casesPlugin.createCase({
-          userId: member.id,
-          modId: kickAuditLogEntry.user.id,
-          type: CaseTypes.Kick,
-          auditLogId: kickAuditLogEntry.id,
-          reason: kickAuditLogEntry.reason || undefined,
-          automatic: true,
-        });
-      }
+        mod = await resolveUser(pluginData.client, kickAuditLogEntry.user.id);
 
-      pluginData.state.serverLogs.log(LogType.MEMBER_KICK, {
-        user: stripObjectToScalars(member.user),
-        mod: stripObjectToScalars(kickAuditLogEntry.user),
-        caseNumber: createdCase.case_number,
-      });
+        const config = mod instanceof UnknownUser ? pluginData.config.get() : pluginData.config.getForUser(mod);
+
+        if (config.create_cases_for_manual_actions) {
+          const casesPlugin = pluginData.getPlugin(CasesPlugin);
+          createdCase = await casesPlugin.createCase({
+            userId: member.id,
+            modId: kickAuditLogEntry.user.id,
+            type: CaseTypes.Kick,
+            auditLogId: kickAuditLogEntry.id,
+            reason: kickAuditLogEntry.reason || undefined,
+            automatic: true,
+          });
+        }
+      }
     }
+
+    pluginData.state.serverLogs.log(LogType.MEMBER_KICK, {
+      user: stripObjectToScalars(member.user),
+      mod: mod ? stripObjectToScalars(mod) : null,
+      caseNumber: createdCase?.case_number ?? 0,
+    });
   },
 );
diff --git a/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts b/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts
index acd7e57f..e41e87a5 100644
--- a/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts
+++ b/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts
@@ -7,6 +7,7 @@ import { CaseTypes } from "../../../data/CaseTypes";
 import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry";
 import { stripObjectToScalars, resolveUser, UnknownUser } from "../../../utils";
 import { LogType } from "../../../data/LogType";
+import { Case } from "../../../data/entities/Case";
 
 /**
  * Create an UNBAN case automatically when a user is unbanned manually.
@@ -28,7 +29,7 @@ export const CreateUnbanCaseOnManualUnbanEvt = modActionsEvt(
 
     const casesPlugin = pluginData.getPlugin(CasesPlugin);
 
-    let createdCase;
+    let createdCase: Case | null = null;
     let mod: User | UnknownUser | null = null;
 
     if (relevantAuditLogEntry) {
@@ -36,27 +37,34 @@ export const CreateUnbanCaseOnManualUnbanEvt = modActionsEvt(
       const auditLogId = relevantAuditLogEntry.id;
 
       mod = await resolveUser(pluginData.client, modId);
-      createdCase = await casesPlugin.createCase({
-        userId: user.id,
-        modId,
-        type: CaseTypes.Unban,
-        auditLogId,
-        automatic: true,
-      });
+
+      const config = mod instanceof UnknownUser ? pluginData.config.get() : pluginData.config.getForUser(mod);
+
+      if (config.create_cases_for_manual_actions) {
+        createdCase = await casesPlugin.createCase({
+          userId: user.id,
+          modId,
+          type: CaseTypes.Unban,
+          auditLogId,
+          automatic: true,
+        });
+      }
     } else {
-      createdCase = await casesPlugin.createCase({
-        userId: user.id,
-        modId: "0",
-        type: CaseTypes.Unban,
-        automatic: true,
-      });
+      const config = pluginData.config.get();
+      if (config.create_cases_for_manual_actions) {
+        createdCase = await casesPlugin.createCase({
+          userId: user.id,
+          modId: "0",
+          type: CaseTypes.Unban,
+          automatic: true,
+        });
+      }
     }
 
-    mod = await mod;
     pluginData.state.serverLogs.log(LogType.MEMBER_UNBAN, {
       mod: mod ? stripObjectToScalars(mod, ["user"]) : null,
       userId: user.id,
-      caseNumber: createdCase.case_number,
+      caseNumber: createdCase?.case_number ?? 0,
     });
   },
 );
diff --git a/backend/src/plugins/ModActions/types.ts b/backend/src/plugins/ModActions/types.ts
index b4db3610..a6cd96c4 100644
--- a/backend/src/plugins/ModActions/types.ts
+++ b/backend/src/plugins/ModActions/types.ts
@@ -37,6 +37,7 @@ export const ConfigSchema = t.type({
   can_hidecase: t.boolean,
   can_deletecase: t.boolean,
   can_act_as_other: t.boolean,
+  create_cases_for_manual_actions: t.boolean,
 });
 export type TConfigSchema = t.TypeOf<typeof ConfigSchema>;