This commit is contained in:
Luna Mendes 2017-12-07 21:54:46 -03:00
parent a0352ef1b1
commit 3412c5c0b9
3 changed files with 106 additions and 62 deletions

View file

@ -76,7 +76,7 @@ class Rsudo(Cog):
return users[0] return users[0]
async def create_request(self, message): async def request(self, message, wait=False):
command_channel = self.bot.get_channel( command_channel = self.bot.get_channel(
self.bot.config.command_channel self.bot.config.command_channel
) )
@ -142,6 +142,9 @@ class Rsudo(Cog):
await msg.edit(embed=embed) await msg.edit(embed=embed)
# todo: does this not execute in the wrong directory? # todo: does this not execute in the wrong directory?
if wait:
return True
else:
out = await shell(command) out = await shell(command)
# output may be very long # output may be very long
@ -168,6 +171,9 @@ class Rsudo(Cog):
await msg.edit(embed=embed) await msg.edit(embed=embed)
if wait:
return False
try: try:
# await user.send(f'Your request for the command {command} was denied.') # await user.send(f'Your request for the command {command} was denied.')
pass pass

View file

@ -1,3 +1,7 @@
env = 'test'
owner_id = 162819866682851329
db = { db = {
'user': 'abc', 'user': 'abc',
'password': 'def', 'password': 'def',
@ -5,10 +9,14 @@ db = {
'host': 'localhost' 'host': 'localhost'
} }
bot_token = 'Mzg2Mjc1MDc3MzY2NDgwODk4.DQNi9A.BnyE5MnKaIaVMBbWiW9rVDwkrSs' if env == 'test':
owner_id = 162819866682851329 # test
bot_token = 'MjExODg5MDEyNzQ5NzYyNTYw.DQttvA.dRkggolnj7csbzg3Y28d45KbAf4'
else:
# prod
bot_token = 'Mzg2Mjc1MDc3MzY2NDgwODk4.DQNi9A.BnyE5MnKaIaVMBbWiW9rVDwkrSs'
command_channel = 386989864014446612 command_channel = 212201893391237121
sexr_chan = 386990164896907264 sexr_chan = 212201893391237121
admin_role = 386566510803681280 admin_role = 349563478530326529

View file

@ -15,7 +15,7 @@ import asyncpg
import config import config
from bot import schedule_bot from bot import schedule_bot
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.DEBUG)
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
db = None db = None
bot = None bot = None
@ -27,6 +27,7 @@ bot = None
# for reader: # for reader:
# - op 1 : log # - op 1 : log
# - op 2 : rsudo # - op 2 : rsudo
# - op 3 : rsudo with steroids
async def wrap(coro): async def wrap(coro):
@ -62,39 +63,57 @@ def parse_logstr(string):
return int(uid), cwd, command return int(uid), cwd, command
async def read_msg(reader): class MemeClient:
header = await reader.read(8) """MemeD client handler."""
def __init__(self, reader, writer):
self.reader = reader
self.writer = writer
async def read_msg(self) -> str:
header = await self.reader.read(8)
log.debug('[recv] %r', header) log.debug('[recv] %r', header)
length, op = struct.unpack('Ii', header) length, op = struct.unpack('Ii', header)
data = await reader.read(length) data = await self.reader.read(length)
data = data.decode() data = data.decode()
log.debug('[recv] %d %d %s', length, op, data) log.debug('[recv] %d %d %s', length, op, data)
return op, data return op, data
async def read_payload(self) -> dict:
async def read_payload(reader): op, message = await self.read_msg()
op, message = await read_msg(reader)
if op > 10: if op > 10:
return op, json.loads(message) return op, json.loads(message)
else: else:
return op, message return op, message
async def send_msg(self, op: int, data: str) -> 'None':
"""Send a message.
async def send_msg(writer, op: int, data: str): This does not wait for the receiving end
to properly finish their buffers.
Arguments
---------
op: int
OP code to be sent.
data: str
Message to be sent with the op code.
"""
header = struct.pack('Ii', len(data), op).decode() header = struct.pack('Ii', len(data), op).decode()
msg = f'{header}{data}'.encode() msg = f'{header}{data}'.encode()
log.debug('[send] %d, %s -> %r', op, data, msg) log.debug('[send] %d, %s -> %r', op, data, msg)
writer.write(msg) self.writer.write(msg)
asyncio.get_event_loop().create_task(wrap(writer.drain))
# Utils can close this early
# and make writer.drain kill itself
# so we wrap on a task which is isolated
asyncio.get_event_loop().create_task(wrap(self.writer.drain))
async def process(reader, writer, op: int, message: str): async def process(self, op: int, message: str) -> 'None':
"""Process messages given through the socket""" """Process a message given through the socket"""
if op == 1: if op == 1:
uid, cwd, command = parse_logstr(message) uid, cwd, command = parse_logstr(message)
log.info('[process] Logging command uid=%d cwd=%r cmd=%r', log.info('[process] Logging command uid=%d cwd=%r cmd=%r',
uid, cwd, command) uid, cwd, command)
@ -102,37 +121,48 @@ async def process(reader, writer, op: int, message: str):
INSERT INTO logs (uid, cwd, cmd) VALUES ($1, $2, $3) INSERT INTO logs (uid, cwd, cmd) VALUES ($1, $2, $3)
""", uid, cwd, command) """, uid, cwd, command)
elif op == 2: elif op == 2:
# Handle rsudo without waiting
if not bot: if not bot:
return await send_msg(writer, 1, 'no bot up') return await self.send_msg(1, 'no bot up')
rsudo = bot.get_cog('Rsudo') rsudo = bot.get_cog('Rsudo')
if not rsudo: if not rsudo:
return await send_msg(writer, 1, 'no rsudo cog') return await self.send_msg(1, 'no rsudo cog')
log.info('[process] got rsudo! %r', message) log.info('[process] got rsudo! %r', message)
await rsudo.create_request(message) self.loop.create_task(rsudo.request(message))
return await send_msg(writer, 1, 'ok') return await self.send_msg(1, int(True))
elif op == 3:
# handle rsudo, waitinG
if not bot:
return await self.send_msg(1, 'no bot')
rsudo = bot.get_cog('Rsudo')
if not rsudo:
return await self.send_msg(1, 'no rsudo cog')
log.info('[process - wait] %r', message)
ok = await rsudo.request(message, True)
return await self.send_msg(1, int(ok))
async def loop(self):
try:
while True:
op, message = await self.read_msg()
await self.process(op, message)
except ConnectionError as e:
log.warning('conn err: %r', e)
except Exception:
log.exception('error at loop')
self.writer.close()
async def handle_client(reader, writer): async def handle_client(reader, writer):
"""Handle clients""" """Handle clients"""
try: client = MemeClient(reader, writer)
asyncio.get_event_loop().create_task(send_msg(writer, 0, 'hello'))
while True: await client.send_msg(0, 'hello')
op, message = await read_msg(reader) await client.loop()
addr = writer.get_extra_info('peername')
log.debug('received %r from %s', message, addr)
await process(reader, writer, op, message)
writer.close()
except ConnectionError as e:
log.warning('connection err: %r', e)
except Exception as e:
log.exception('error at handler coro')
writer.close()
if __name__ == '__main__': if __name__ == '__main__':