Entirely remove db portion in bot and handle kickban cmds in webapp

This commit is contained in:
Jeremy Zhang 2018-08-10 04:13:56 +00:00
parent c3a91ff29a
commit cb0f1b249e
7 changed files with 110 additions and 114 deletions

View File

@ -5,6 +5,8 @@ config = {
'redis-uri': "redis://",
'titan-web-url': "https://titanembeds.com/",
'discord-bots-org-token': "DiscordBots.org Post Stats Token",
'bots-discord-pw-token': "bots.discord.pw Post Stats Token",

View File

@ -1,5 +1,4 @@
from config import config
from titanembeds.database import DatabaseInterface
from titanembeds.redisqueue import RedisQueue
from titanembeds.commands import Commands
from titanembeds.socketio import SocketIOInterface
@ -27,9 +26,8 @@ class Titan(discord.AutoShardedClient):
super().__init__(max_messages=20000)
self.aiosession = aiohttp.ClientSession(loop=self.loop)
self.http.user_agent += ' TitanEmbeds-Bot'
self.database = DatabaseInterface(self)
self.redisqueue = RedisQueue(self, config["redis-uri"])
self.command = Commands(self, self.database)
self.command = Commands(self, config)
self.socketio = SocketIOInterface(self, config["redis-uri"])
self.delete_list = deque(maxlen=100) # List of msg ids to prevent duplicate delete
@ -64,7 +62,6 @@ class Titan(discord.AutoShardedClient):
self.loop.close()
async def start(self):
await self.database.connect(config["database-uri"])
await self.redisqueue.connect()
self.loop.create_task(self.redisqueue.subscribe())
await super().start(config["bot-token"])

View File

@ -1,13 +1,14 @@
import aiohttp
class Commands():
def __init__(self, client, database):
def __init__(self, client, config):
self.client = client
self.database = database
self.config = config
async def ban(self, message):
if not message.author.guild_permissions.ban_members:
await message.channel.send(message.author.mention + " I'm sorry, but you do not have permissions to ban guest members.")
return
serverid = message.guild.id
content = message.content.strip()
if len(content.split()) == 2:
await message.channel.send(message.author.mention + " Please provide a username-query (or optionally a discriminator) to ban a guest user.\nExample: `ban Titan#0001`")
@ -15,14 +16,30 @@ class Commands():
content = content.split()
username = content[2][:content[2].find("#")] if "#" in content[2] else content[2]
discriminator = int(content[2][content[2].find("#") + 1:]) if "#" in content[2] else None
reason = await self.database.ban_unauth_user_by_query(message.guild.id, message.author.id, username, discriminator)
await message.channel.send(message.author.mention + " " + reason)
headers = {"Authorization": self.config["bot-token"]}
payload = {
"guild_id": message.guild.id,
"placer_id": message.author.id,
"username": username
}
if discriminator:
payload["discriminator"] = discriminator
url = self.config["titan-web-url"] + "api/bot/ban"
async with aiohttp.ClientSession() as aioclient:
async with aioclient.post(url, json=payload, headers=headers) as resp:
j = await resp.json()
if "error" in j:
await message.channel.send(message.author.mention + " Ban error! " + j["error"])
return
if "success" in j:
await message.channel.send(message.author.mention + " " + j["success"])
return
await message.channel.send("Unhandled webservice error in banning guest user!")
async def kick(self, message):
if not message.author.guild_permissions.kick_members:
await message.channel.send(message.author.mention + " I'm sorry, but you do not have permissions to kick guest members.")
return
serverid = message.guild.id
content = message.content.strip()
if len(content.split()) == 2:
await message.channel.send(message.author.mention + " Please provide a username-query (or optionally a discriminator) to kick a guest user.\nExample: `kick Titan#0001`")
@ -30,8 +47,24 @@ class Commands():
content = content.split()
username = content[2][:content[2].find("#")] if "#" in content[2] else content[2]
discriminator = int(content[2][content[2].find("#") + 1:]) if "#" in content[2] else None
reason = await self.database.revoke_unauth_user_by_query(message.guild.id, username, discriminator)
await message.channel.send(message.author.mention + " " + reason)
headers = {"Authorization": self.config["bot-token"]}
payload = {
"guild_id": message.guild.id,
"username": username
}
if discriminator:
payload["discriminator"] = discriminator
url = self.config["titan-web-url"] + "api/bot/revoke"
async with aiohttp.ClientSession() as aioclient:
async with aioclient.post(url, json=payload, headers=headers) as resp:
j = await resp.json()
if "error" in j:
await message.channel.send(message.author.mention + " Kick error! " + j["error"])
return
if "success" in j:
await message.channel.send(message.author.mention + " " + j["success"])
return
await message.channel.send("Unhandled webservice error in kicking guest user!")
async def invite(self, message):
await message.channel.send("You can invite Titan to your server by visiting this link: https://discordapp.com/oauth2/authorize?&client_id=299403260031139840&scope=bot&permissions=641195117")

View File

@ -1,76 +0,0 @@
from gino import Gino
import json
import discord
import datetime
db = Gino()
from titanembeds.database.unauthenticated_users import UnauthenticatedUsers
from titanembeds.database.unauthenticated_bans import UnauthenticatedBans
from titanembeds.utils import get_message_author, get_message_mentions, get_webhooks_list, get_emojis_list, get_roles_list, get_channels_list, list_role_ids, get_attachments_list, get_embeds_list
class DatabaseInterface(object):
def __init__(self, bot):
self.bot = bot
async def connect(self, dburi):
await db.set_bind(dburi)
async def ban_unauth_user_by_query(self, guild_id, placer_id, username, discriminator):
dbuser = None
if discriminator:
dbuser = await UnauthenticatedUsers.query \
.where(UnauthenticatedUsers.guild_id == int(guild_id)) \
.where(UnauthenticatedUsers.username.ilike("%" + username + "%")) \
.where(UnauthenticatedUsers.discriminator == discriminator) \
.order_by(UnauthenticatedUsers.id.desc()).gino.first()
else:
dbuser = await UnauthenticatedUsers.query \
.where(UnauthenticatedUsers.guild_id == int(guild_id)) \
.where(UnauthenticatedUsers.username.ilike("%" + username + "%")) \
.order_by(UnauthenticatedUsers.id.desc()).gino.first()
if not dbuser:
return "Ban error! Guest user cannot be found."
dbban = await UnauthenticatedBans.query \
.where(UnauthenticatedBans.guild_id == int(guild_id)) \
.where(UnauthenticatedBans.last_username == dbuser.username) \
.where(UnauthenticatedBans.last_discriminator == dbuser.discriminator).gino.first()
if dbban is not None:
if dbban.lifter_id is None:
return "Ban error! Guest user, **{}#{}**, has already been banned.".format(dbban.last_username, dbban.last_discriminator)
await dbban.delete()
dbban = await UnauthenticatedBans.create(
guild_id = int(guild_id),
ip_address = dbuser.ip_address,
last_username = dbuser.username,
last_discriminator = dbuser.discriminator,
timestamp = datetime.datetime.now(),
reason = "",
lifter_id = None,
placer_id = int(placer_id)
)
return "Guest user, **{}#{}**, has successfully been added to the ban list!".format(dbban.last_username, dbban.last_discriminator)
async def revoke_unauth_user_by_query(self, guild_id, username, discriminator):
dbuser = None
if discriminator:
dbuser = await UnauthenticatedUsers.query \
.where(UnauthenticatedUsers.guild_id == int(guild_id)) \
.where(UnauthenticatedUsers.username.ilike("%" + username + "%")) \
.where(UnauthenticatedUsers.discriminator == discriminator) \
.order_by(UnauthenticatedUsers.id.desc()).gino.first()
else:
dbuser = await UnauthenticatedUsers.query \
.where(UnauthenticatedUsers.guild_id == int(guild_id)) \
.where(UnauthenticatedUsers.username.ilike("%" + username + "%")) \
.order_by(UnauthenticatedUsers.id.desc()).gino.first()
if not dbuser:
return "Kick error! Guest user cannot be found."
elif dbuser.revoked:
return "Kick error! Guest user **{}#{}** has already been kicked!".format(dbuser.username, dbuser.discriminator)
await dbuser.update(revoked = True).apply()
return "Successfully kicked **{}#{}**!".format(dbuser.username, dbuser.discriminator)
async def delete_all_messages_from_channel(self, channel_id):
await Messages.delete.where(Messages.channel_id == int(channel_id)).gino.status()

View File

@ -1,15 +0,0 @@
from titanembeds.database import db
import datetime
import time
class UnauthenticatedBans(db.Model):
__tablename__ = "unauthenticated_bans"
id = db.Column(db.Integer, primary_key=True) # Auto increment id
guild_id = db.Column(db.String(255)) # Guild pretaining to the unauthenticated user
ip_address = db.Column(db.String(255)) # The IP Address of the user
last_username = db.Column(db.String(255)) # The username when they got banned
last_discriminator = db.Column(db.Integer) # The discrim when they got banned
timestamp = db.Column(db.TIMESTAMP) # The timestamp of when the user got banned
reason = db.Column(db.Text()) # The reason of the ban set by the guild moderators
lifter_id = db.Column(db.BigInteger) # Discord Client ID of the user who lifted the ban
placer_id = db.Column(db.BigInteger) # The id of who placed the ban

View File

@ -1,11 +0,0 @@
from titanembeds.database import db
class UnauthenticatedUsers(db.Model):
__tablename__ = "unauthenticated_users"
id = db.Column(db.Integer, primary_key=True) # Auto increment id
guild_id = db.Column(db.BigInteger) # Guild pretaining to the unauthenticated user
username = db.Column(db.String(255)) # The username of the user
discriminator = db.Column(db.Integer) # The discriminator to distinguish unauth users with each other
user_key = db.Column(db.Text()) # The secret key used to identify the user holder
ip_address = db.Column(db.String(255)) # The IP Address of the user
revoked = db.Column(db.Boolean()) # If the user's key has been revoked and a new one is required to be generated

View File

@ -551,6 +551,72 @@ def webhook_discordbotsorg_vote():
db.session.commit()
return ('', 204)
@api.route("/bot/ban", methods=["POST"])
def bot_ban():
if request.headers.get("Authorization", "") != config.get("bot-token", ""):
return jsonify(error="Authorization header does not match."), 403
incoming = request.get_json()
guild_id = incoming.get("guild_id", None)
placer_id = incoming.get("placer_id", None)
username = incoming.get("username", None)
discriminator = incoming.get("discriminator", None)
if not guild_id or not placer_id or not username:
return jsonify(error="Missing required parameters."), 400
if discriminator:
dbuser = db.session.query(UnauthenticatedUsers) \
.filter(UnauthenticatedUsers.guild_id == int(guild_id)) \
.filter(UnauthenticatedUsers.username.ilike("%" + username + "%")) \
.filter(UnauthenticatedUsers.discriminator == discriminator) \
.order_by(UnauthenticatedUsers.id.desc()).first()
else:
dbuser = db.session.query(UnauthenticatedUsers) \
.filter(UnauthenticatedUsers.guild_id == int(guild_id)) \
.filter(UnauthenticatedUsers.username.ilike("%" + username + "%")) \
.order_by(UnauthenticatedUsers.id.desc()).first()
if not dbuser:
return jsonify(error="Guest user cannot be found."), 404
dbban = db.session.query(UnauthenticatedBans) \
.filter(UnauthenticatedBans.guild_id == int(guild_id)) \
.filter(UnauthenticatedBans.last_username == dbuser.username) \
.filter(UnauthenticatedBans.last_discriminator == dbuser.discriminator).first()
if dbban is not None:
if dbban.lifter_id is None:
return jsonify(error="Guest user, **{}#{}**, has already been banned.".format(dbban.last_username, dbban.last_discriminator)), 409
db.session.delete(dbban)
dbban = UnauthenticatedBans(int(guild_id), dbuser.ip_address, dbuser.username, dbuser.discriminator, "", int(placer_id))
db.session.add(dbban)
db.session.commit()
return jsonify(success="Guest user, **{}#{}**, has successfully been added to the ban list!".format(dbban.last_username, dbban.last_discriminator))
@api.route("/bot/revoke", methods=["POST"])
def bot_revoke():
if request.headers.get("Authorization", "") != config.get("bot-token", ""):
return jsonify(error="Authorization header does not match."), 403
incoming = request.get_json()
guild_id = incoming.get("guild_id", None)
username = incoming.get("username", None)
discriminator = incoming.get("discriminator", None)
if not guild_id or not username:
return jsonify(error="Missing required parameters."), 400
if discriminator:
dbuser = db.session.query(UnauthenticatedUsers) \
.filter(UnauthenticatedUsers.guild_id == int(guild_id)) \
.filter(UnauthenticatedUsers.username.ilike("%" + username + "%")) \
.filter(UnauthenticatedUsers.discriminator == discriminator) \
.order_by(UnauthenticatedUsers.id.desc()).first()
else:
dbuser = db.session.query(UnauthenticatedUsers) \
.filter(UnauthenticatedUsers.guild_id == int(guild_id)) \
.filter(UnauthenticatedUsers.username.ilike("%" + username + "%")) \
.order_by(UnauthenticatedUsers.id.desc()).first()
if not dbuser:
return jsonify(error="Guest user cannot be found."), 404
elif dbuser.revoked:
return jsonify(error="Guest user **{}#{}** has already been kicked!".format(dbuser.username, dbuser.discriminator)), 409
dbuser.revoked = True
db.session.commit()
return jsonify(success="Successfully kicked **{}#{}**!".format(dbuser.username, dbuser.discriminator))
@api.route("/af/direct_message", methods=["POST"])
def af_direct_message_post():
cs = request.form.get('cs', None)