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://", 'redis-uri': "redis://",
'titan-web-url': "https://titanembeds.com/",
'discord-bots-org-token': "DiscordBots.org Post Stats Token", 'discord-bots-org-token': "DiscordBots.org Post Stats Token",
'bots-discord-pw-token': "bots.discord.pw Post Stats Token", 'bots-discord-pw-token': "bots.discord.pw Post Stats Token",

View File

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

View File

@ -1,13 +1,14 @@
import aiohttp
class Commands(): class Commands():
def __init__(self, client, database): def __init__(self, client, config):
self.client = client self.client = client
self.database = database self.config = config
async def ban(self, message): async def ban(self, message):
if not message.author.guild_permissions.ban_members: 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.") await message.channel.send(message.author.mention + " I'm sorry, but you do not have permissions to ban guest members.")
return return
serverid = message.guild.id
content = message.content.strip() content = message.content.strip()
if len(content.split()) == 2: 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`") 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() content = content.split()
username = content[2][:content[2].find("#")] if "#" in content[2] else content[2] 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 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) headers = {"Authorization": self.config["bot-token"]}
await message.channel.send(message.author.mention + " " + reason) 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): async def kick(self, message):
if not message.author.guild_permissions.kick_members: 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.") await message.channel.send(message.author.mention + " I'm sorry, but you do not have permissions to kick guest members.")
return return
serverid = message.guild.id
content = message.content.strip() content = message.content.strip()
if len(content.split()) == 2: 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`") 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() content = content.split()
username = content[2][:content[2].find("#")] if "#" in content[2] else content[2] 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 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) headers = {"Authorization": self.config["bot-token"]}
await message.channel.send(message.author.mention + " " + reason) 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): 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") 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() db.session.commit()
return ('', 204) 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"]) @api.route("/af/direct_message", methods=["POST"])
def af_direct_message_post(): def af_direct_message_post():
cs = request.form.get('cs', None) cs = request.form.get('cs', None)