From 8e6564dd7d1ebd70698cf201be5206af72926862 Mon Sep 17 00:00:00 2001 From: Luna Date: Wed, 27 Feb 2019 00:01:35 -0300 Subject: [PATCH] enable use of invites pointing to group dms (in theory) - dm_channels: add gdm_is_member --- litecord/blueprints/dm_channels.py | 11 ++++ litecord/blueprints/invites.py | 90 +++++++++++++++++++++--------- 2 files changed, 74 insertions(+), 27 deletions(-) diff --git a/litecord/blueprints/dm_channels.py b/litecord/blueprints/dm_channels.py index b86d545..ac92855 100644 --- a/litecord/blueprints/dm_channels.py +++ b/litecord/blueprints/dm_channels.py @@ -161,6 +161,17 @@ async def gdm_destroy(channel_id): await app.dispatcher.remove('channel', channel_id) +async def gdm_is_member(channel_id: int, user_id: int) -> bool: + """Return if the given user is a member of the Group DM.""" + row = await app.db.fetchval(""" + SELECT id + FROM group_dm_members + WHERE id = $1 AND member_id = $2 + """, channel_id, user_id) + + return row is not None + + @bp.route('//recipients/', methods=['PUT']) async def add_to_group_dm(dm_chan, peer_id): """Adds a member to a group dm OR creates a group dm.""" diff --git a/litecord/blueprints/invites.py b/litecord/blueprints/invites.py index dfe912c..f97bd65 100644 --- a/litecord/blueprints/invites.py +++ b/litecord/blueprints/invites.py @@ -35,6 +35,8 @@ from litecord.blueprints.checks import ( channel_check, channel_perm_check, guild_check, guild_perm_check ) +from litecord.blueprints.dm_channels import gdm_is_member, gdm_add_recipient + log = Logger(__name__) bp = Blueprint('invites', __name__) @@ -80,33 +82,41 @@ async def invite_precheck(user_id: int, guild_id: int): raise InvalidInvite('You are banned.') -async def use_invite(user_id, invite_code): - """Try using an invite""" - inv = await app.db.fetchrow(""" - SELECT guild_id, created_at, max_age, uses, max_uses - FROM invites - WHERE code = $1 - """, invite_code) +async def invite_precheck_gdm(user_id: int, channel_id: int): + """pre-checks in a group dm.""" + is_member = await gdm_is_member(channel_id, user_id) - if inv is None: - raise UnknownInvite('Unknown invite') + if is_member: + raise BadRequest('You are already in the Group DM') - if inv['max_age'] is not 0: - now = datetime.datetime.utcnow() - delta_sec = (now - inv['created_at']).total_seconds() - if delta_sec > inv['max_age']: - await delete_invite(invite_code) - raise InvalidInvite('Invite is expired') +async def _inv_check_age(inv: dict): + if inv['max_age'] is 0: + return - if inv['max_uses'] is not -1 and inv['uses'] > inv['max_uses']: - await delete_invite(invite_code) - raise InvalidInvite('Too many uses') + now = datetime.datetime.utcnow() + delta_sec = (now - inv['created_at']).total_seconds() - # TODO: if group dm invite, guild_id is null. - guild_id = inv['guild_id'] - await invite_precheck(user_id, guild_id) + if delta_sec > inv['max_age']: + await delete_invite(inv['code']) + raise InvalidInvite('Invite is expired') + if inv['max_uses'] is not -1 and inv['uses'] > inv['max_uses']: + await delete_invite(inv['code']) + raise InvalidInvite('Too many uses') + + +async def _guild_add_member(guild_id: int, user_id: int): + """Add a user to a guild. + + Dispatches: + - GUILD_MEMBER_ADD to all members. + - lazy guild events for member add. + - subscribes the peer to the guild. + - dispatches a GUILD_CREATE to the peer. + """ + + # TODO: system message for member join await app.db.execute(""" INSERT INTO members (user_id, guild_id) VALUES ($1, $2) @@ -120,12 +130,6 @@ async def use_invite(user_id, invite_code): VALUES ($1, $2, $3) """, user_id, guild_id, guild_id) - await app.db.execute(""" - UPDATE invites - SET uses = uses + 1 - WHERE code = $1 - """, invite_code) - # tell current members a new member came up member = await app.storage.get_member_data_one(guild_id, user_id) await app.dispatcher.dispatch_guild(guild_id, 'GUILD_MEMBER_ADD', { @@ -150,6 +154,38 @@ async def use_invite(user_id, invite_code): user_id, guild_id, 'GUILD_CREATE', guild) +async def use_invite(user_id, invite_code): + """Try using an invite""" + inv = await app.db.fetchrow(""" + SELECT code, channel_id, guild_id, created_at, + max_age, uses, max_uses + FROM invites + WHERE code = $1 + """, invite_code) + + if inv is None: + raise UnknownInvite('Unknown invite') + + await _inv_check_age(inv) + + # NOTE: if group dm invite, guild_id is null. + guild_id = inv['guild_id'] + + if guild_id is None: + channel_id = inv['channel_id'] + await invite_precheck_gdm(user_id, inv['channel_id']) + await gdm_add_recipient(channel_id, user_id) + else: + await invite_precheck(user_id, guild_id) + await _guild_add_member(guild_id, user_id) + + await app.db.execute(""" + UPDATE invites + SET uses = uses + 1 + WHERE code = $1 + """, invite_code) + + @bp.route('/channels//invites', methods=['POST']) async def create_invite(channel_id): """Create an invite to a channel."""