Added Audit system, Guild auditing put on hold

This commit is contained in:
Ean Milligan (Bastion) 2022-05-28 02:07:00 -04:00
parent b7f9fc852a
commit a01b8b8fd2
13 changed files with 204 additions and 9 deletions

View File

@ -10,6 +10,7 @@ await dbClient.execute(`USE ${config.db.name}`);
console.log('DB created'); console.log('DB created');
console.log('Attempt to drop all tables'); console.log('Attempt to drop all tables');
await dbClient.execute(`DROP VIEW IF EXISTS db_size;`);
await dbClient.execute(`DROP TABLE IF EXISTS allowed_channels;`); await dbClient.execute(`DROP TABLE IF EXISTS allowed_channels;`);
await dbClient.execute(`DROP TABLE IF EXISTS all_keys;`); await dbClient.execute(`DROP TABLE IF EXISTS all_keys;`);
await dbClient.execute(`DROP TABLE IF EXISTS allowed_guilds;`); await dbClient.execute(`DROP TABLE IF EXISTS allowed_guilds;`);
@ -110,5 +111,20 @@ await dbClient.execute(`
`); `);
console.log('Table created'); console.log('Table created');
// Database sizes view
console.log('Attempting to create view db_size');
await dbClient.execute(`
CREATE VIEW db_size AS
SELECT
table_name AS "table",
ROUND(((data_length + index_length) / 1024 / 1024), 3) AS "size",
table_rows AS "rows"
FROM information_schema.TABLES
WHERE
table_schema = "${config.db.name}"
AND table_name <> "db_size";
`);
console.log('View Created');
await dbClient.close(); await dbClient.close();
console.log('Done!'); console.log('Done!');

View File

@ -10,7 +10,7 @@ await dbClient.execute('INSERT INTO all_keys(userid,apiKey) values(?,?)', [confi
console.log('Inesrtion done'); console.log('Inesrtion done');
console.log('Attempting to insert default commands into command_cnt'); console.log('Attempting to insert default commands into command_cnt');
const commands = ['ping', 'rip', 'rollhelp', 'help', 'info', 'version', 'report', 'stats', 'roll', 'emojis', 'api', 'privacy', 'mention']; const commands = ['ping', 'rip', 'rollhelp', 'help', 'info', 'version', 'report', 'stats', 'roll', 'emojis', 'api', 'privacy', 'mention', 'audit'];
for (const command of commands) { for (const command of commands) {
await dbClient.execute('INSERT INTO command_cnt(command) values(?)', [command]).catch((e) => { await dbClient.execute('INSERT INTO command_cnt(command) values(?)', [command]).catch((e) => {
console.log(`Failed to insert ${command} into database`, e); console.log(`Failed to insert ${command} into database`, e);

View File

@ -8,7 +8,7 @@ export {
} from "https://deno.land/x/discordeno@12.0.1/mod.ts"; } from "https://deno.land/x/discordeno@12.0.1/mod.ts";
export type { export type {
DiscordenoMessage, DiscordenoGuild, CreateMessage DiscordenoMessage, DiscordenoGuild, CreateMessage, EmbedField
} from "https://deno.land/x/discordeno@12.0.1/mod.ts"; } from "https://deno.land/x/discordeno@12.0.1/mod.ts";
export { Client } from "https://deno.land/x/mysql@v2.10.2/mod.ts"; export { Client } from "https://deno.land/x/mysql@v2.10.2/mod.ts";

5
mod.ts
View File

@ -190,6 +190,11 @@ startBot({
// API sub commands // API sub commands
commands.api(message, args); commands.api(message, args);
break; break;
case 'audit':
// [[audit arg
// Audit sub commands
commands.audit(message, args);
break;
default: default:
// Non-standard commands // Non-standard commands
if (command?.startsWith('xdy')) { if (command?.startsWith('xdy')) {

View File

@ -27,6 +27,7 @@ export const generateStats = (guildCount: number, channelCount: number, memberCo
embeds: [{ embeds: [{
color: infoColor2, color: infoColor2,
title: 'The Artificer\'s Statistics:', title: 'The Artificer\'s Statistics:',
timestamp: new Date().toISOString(),
fields: [ fields: [
{ {
name: 'Guilds:', name: 'Guilds:',

View File

@ -11,6 +11,7 @@ import { api } from './apiCmd.ts';
import { emoji } from './emoji.ts'; import { emoji } from './emoji.ts';
import { roll } from './roll.ts'; import { roll } from './roll.ts';
import { handleMentions } from './handleMentions.ts'; import { handleMentions } from './handleMentions.ts';
import { audit } from './audit.ts';
export default { export default {
ping, ping,
@ -26,4 +27,5 @@ export default {
emoji, emoji,
roll, roll,
handleMentions, handleMentions,
audit,
}; };

54
src/commands/audit.ts Normal file
View File

@ -0,0 +1,54 @@
import config from '../../config.ts';
import { dbClient } from '../db.ts';
import {
// Discordeno deps
DiscordenoMessage,
// Log4Deno deps
log,
LT,
} from '../../deps.ts';
import auditCommands from './auditCmd/_index.ts';
import { failColor } from '../commandUtils.ts';
export const audit = async (message: DiscordenoMessage, args: string[]) => {
// Light telemetry to see how many times a command is being run
dbClient.execute(`CALL INC_CNT("audit");`).catch((e) => {
log(LT.ERROR, `Failed to call stored procedure INC_CNT: ${JSON.stringify(e)}`);
});
// Local apiArg in lowercase
const auditArg = (args[0] || 'help').toLowerCase();
// Makes sure the user is authenticated to run the API command
if (message.authorId === config.api.admin) {
switch (auditArg) {
case 'help':
case 'h':
// [[audit help or [[audit h
// Shows API help details
auditCommands.auditHelp(message);
break;
case 'db':
// [[audit db
// Shows current DB table sizes
auditCommands.auditDB(message);
break;
case 'guilds':
// [[audit guilds
// Shows breakdown of guilds and detials on them
auditCommands.auditGuilds(message);
break;
default:
break;
}
} else {
message.send({
embeds: [{
color: failColor,
title: `Audit commands are powerful and can only be used by ${config.name}'s owner.`,
}],
}).catch((e) => {
log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`);
});
}
};

View File

@ -0,0 +1,9 @@
import { auditHelp } from './auditHelp.ts';
import { auditDB } from './auditDB.ts';
import { auditGuilds } from './auditGuilds.ts';
export default {
auditHelp,
auditDB,
auditGuilds,
};

View File

@ -0,0 +1,48 @@
import { dbClient } from '../../db.ts';
import {
// Discordeno deps
DiscordenoMessage,
EmbedField,
// Log4Deno deps
log,
LT,
} from '../../../deps.ts';
import { infoColor2 } from '../../commandUtils.ts';
import { compilingStats } from '../../commonEmbeds.ts';
export const auditDB = async (message: DiscordenoMessage) => {
try {
const m = await message.send(compilingStats);
// Get DB statistics
const auditQuery = await dbClient.query(`SELECT * FROM db_size;`).catch((e) => {
log(LT.ERROR, `Failed to query DB: ${JSON.stringify(e)}`);
});
// Turn all tables into embed fields, currently only properly will handle 25 tables, but we'll fix that when artificer gets 26 tables
const embedFields: Array<EmbedField> = [];
auditQuery.forEach((row: any) => {
embedFields.push({
name: `${row.table}`,
value: `**Size:** ${row.size} MB
**Rows:** ${row.rows}`,
inline: true,
});
});
// Send the results
m.edit({
embeds: [{
color: infoColor2,
title: 'Database Audit',
description: 'Lists all tables with their current size and row count.',
timestamp: new Date().toISOString(),
fields: embedFields,
}],
}).catch((e) => {
log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`);
});
} catch (e) {
log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`);
}
};

View File

@ -0,0 +1,21 @@
import {
// Discordeno deps
DiscordenoMessage,
// Log4Deno deps
log,
LT,
} from '../../../deps.ts';
import { infoColor2 } from '../../commandUtils.ts';
export const auditGuilds = (message: DiscordenoMessage) => {
message.send({
embeds: [{
color: infoColor2,
title: 'Guilds Audit',
description: 'WIP',
timestamp: new Date().toISOString(),
}],
}).catch((e) => {
log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`);
});
};

View File

@ -0,0 +1,35 @@
import config from '../../../config.ts';
import {
// Discordeno deps
DiscordenoMessage,
// Log4Deno deps
log,
LT,
} from '../../../deps.ts';
import { infoColor1 } from '../../commandUtils.ts';
export const auditHelp = (message: DiscordenoMessage) => {
message.send({
embeds: [{
color: infoColor1,
title: 'Audit Help',
fields: [
{
name: `\`${config.prefix}audit help\``,
value: 'This command',
inline: true
}, {
name: `\`${config.prefix}audit db\``,
value: 'Shows current DB table sizes',
inline: true
}, {
name: `\`${config.prefix}audit guilds\``,
value: 'Shows breakdown of guilds and detials on them',
inline: true
},
]
}],
}).catch((e) => {
log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`);
});
};

View File

@ -8,7 +8,8 @@ import {
log, log,
LT, LT,
} from '../../deps.ts'; } from '../../deps.ts';
import { generateStats, warnColor } from '../commandUtils.ts'; import { generateStats } from '../commandUtils.ts';
import { compilingStats } from '../commonEmbeds.ts';
export const stats = async (message: DiscordenoMessage) => { export const stats = async (message: DiscordenoMessage) => {
// Light telemetry to see how many times a command is being run // Light telemetry to see how many times a command is being run
@ -17,12 +18,7 @@ export const stats = async (message: DiscordenoMessage) => {
}); });
try { try {
const m = await message.send({ const m = await message.send(compilingStats);
embeds: [{
color: warnColor,
title: 'Compiling latest statistics . . .',
}],
});
// Calculate how many times commands have been run // Calculate how many times commands have been run
const rollQuery = await dbClient.query(`SELECT count FROM command_cnt WHERE command = "roll";`).catch((e) => { const rollQuery = await dbClient.query(`SELECT count FROM command_cnt WHERE command = "roll";`).catch((e) => {

8
src/commonEmbeds.ts Normal file
View File

@ -0,0 +1,8 @@
import { warnColor } from './commandUtils.ts';
export const compilingStats = {
embeds: [{
color: warnColor,
title: 'Compiling latest statistics . . .',
}],
};