Added ability to white or blacklist attachment filetype in automod

Intended to allow certain channels (i.e. bug reporting ones) to only allow .log files with uploads enabled, making it impossible to upload mp4s to troll or similar
This commit is contained in:
Dark 2020-03-20 18:04:37 +01:00 committed by Miikka
parent 22982b8113
commit 2c63509084
2 changed files with 72 additions and 0 deletions

View file

@ -60,10 +60,12 @@ import {
TMatchWordsTrigger,
TMemberJoinTrigger,
TRule,
TMatchAttachmentTypeTrigger,
} from "./types";
import { pluginInfo } from "./info";
import { ERRORS, RecoverablePluginError } from "../../RecoverablePluginError";
import Timeout = NodeJS.Timeout;
import { StrictValidationError } from "src/validatorUtils";
const unactioned = (action: TextRecentAction | OtherRecentAction) => !action.actioned;
@ -116,6 +118,19 @@ const defaultMatchLinksTrigger: Partial<TMatchLinksTrigger> = {
match_custom_status: false,
};
const defaultMatchAttachmentTypeTrigger: Partial<TMatchAttachmentTypeTrigger> = {
filetype_blacklist: [],
blacklist_enabled: false,
filetype_whitelist: [],
whitelist_enabled: false,
match_messages: true,
match_embeds: true,
match_visible_names: false,
match_usernames: false,
match_nicknames: false,
match_custom_status: false,
};
const defaultTextSpamTrigger: Partial<t.TypeOf<typeof BaseTextSpamTrigger>> = {
per_channel: true,
};
@ -130,6 +145,7 @@ const defaultTriggers = {
match_regex: defaultMatchRegexTrigger,
match_invites: defaultMatchInvitesTrigger,
match_links: defaultMatchLinksTrigger,
match_attachment_type: defaultMatchAttachmentTypeTrigger,
message_spam: defaultTextSpamTrigger,
mention_spam: defaultTextSpamTrigger,
link_spam: defaultTextSpamTrigger,
@ -249,6 +265,21 @@ export class AutomodPlugin extends ZeppelinPlugin<TConfigSchema, ICustomOverride
trigger[defaultTriggerName] = configUtils.mergeConfig({}, defaultTrigger, trigger[defaultTriggerName]);
}
}
if (trigger.match_attachment_type) {
const white = trigger.match_attachment_type.whitelist_enabled;
const black = trigger.match_attachment_type.blacklist_enabled;
if (white && black) {
throw new StrictValidationError([
`Cannot have both blacklist and whitelist enabled at rule <${rule.name}/match_attachment_type>`,
]);
} else if (!white && !black) {
throw new StrictValidationError([
`Must have either blacklist or whitelist enabled at rule <${rule.name}/match_attachment_type>`,
]);
}
}
}
}
@ -457,6 +488,23 @@ export class AutomodPlugin extends ZeppelinPlugin<TConfigSchema, ICustomOverride
return null;
}
protected evaluateMatchAttachmentTypeTrigger(trigger: TMatchAttachmentTypeTrigger, msg: SavedMessage): null | string {
if (!msg.data.attachments) return null;
const attachments: any[] = msg.data.attachments;
for (const attachment of attachments) {
const attachment_type = attachment.filename.split(`.`).pop();
if (trigger.blacklist_enabled && trigger.filetype_blacklist.includes(attachment_type)) {
return `${attachment_type} - blacklisted`;
}
if (trigger.whitelist_enabled && !trigger.filetype_whitelist.includes(attachment_type)) {
return `${attachment_type} - not whitelisted`;
}
}
return null;
}
protected matchTextSpamTrigger(
recentActionType: RecentActionType,
trigger: TBaseTextSpamTrigger,
@ -626,6 +674,13 @@ export class AutomodPlugin extends ZeppelinPlugin<TConfigSchema, ICustomOverride
if (match) return { ...match, trigger: "match_links" } as TextTriggerMatchResult;
}
if (trigger.match_attachment_type) {
const match = await this.matchMultipleTextTypesOnMessage(trigger.match_attachment_type, msg, str => {
return this.evaluateMatchAttachmentTypeTrigger(trigger.match_attachment_type, msg);
});
if (match) return { ...match, trigger: "match_attachment_type" } as TextTriggerMatchResult;
}
if (trigger.message_spam) {
const match = this.matchTextSpamTrigger(RecentActionType.Message, trigger.message_spam, msg);
if (match) return { ...match, rule, trigger: "message_spam" };
@ -1319,6 +1374,8 @@ export class AutomodPlugin extends ZeppelinPlugin<TConfigSchema, ICustomOverride
return `invite code \`${disableInlineCode(matchResult.matchedValue)}\``;
} else if (matchResult.trigger === "match_links") {
return `link \`${disableInlineCode(matchResult.matchedValue)}\``;
} else if (matchResult.trigger === "match_attachment_type") {
return `attachment type \`${disableInlineCode(matchResult.matchedValue)}\``;
}
return typeof matchResult.matchedValue === "string" ? `\`${disableInlineCode(matchResult.matchedValue)}\`` : null;

View file

@ -179,6 +179,20 @@ export const MatchLinksTrigger = t.type({
});
export type TMatchLinksTrigger = t.TypeOf<typeof MatchLinksTrigger>;
export const MatchAttachmentTypeTrigger = t.type({
filetype_blacklist: t.array(t.string),
blacklist_enabled: t.boolean,
filetype_whitelist: t.array(t.string),
whitelist_enabled: t.boolean,
match_messages: t.boolean,
match_embeds: t.boolean,
match_visible_names: t.boolean,
match_usernames: t.boolean,
match_nicknames: t.boolean,
match_custom_status: t.boolean,
});
export type TMatchAttachmentTypeTrigger = t.TypeOf<typeof MatchAttachmentTypeTrigger>;
export const BaseSpamTrigger = t.type({
amount: t.number,
within: t.string,
@ -280,6 +294,7 @@ export const Rule = t.type({
match_regex: tNullable(MatchRegexTrigger),
match_invites: tNullable(MatchInvitesTrigger),
match_links: tNullable(MatchLinksTrigger),
match_attachment_type: tNullable(MatchAttachmentTypeTrigger),
message_spam: tNullable(MessageSpamTrigger),
mention_spam: tNullable(MentionSpamTrigger),
link_spam: tNullable(LinkSpamTrigger),