From b92d1302e70a133e672cbf94518bdb592ce7cd93 Mon Sep 17 00:00:00 2001 From: Luna Mendes Date: Thu, 22 Nov 2018 04:45:00 -0300 Subject: [PATCH] users: decouple main dispatch to mass_user_update this should solve problems with people getting nitro and others being able to see their flag status. who knows what happens inside the offical client. - users.billing_job: use mass_user_update --- litecord/blueprints/user/billing_job.py | 8 +-- litecord/blueprints/users.py | 77 ++++++++++++++----------- 2 files changed, 48 insertions(+), 37 deletions(-) diff --git a/litecord/blueprints/user/billing_job.py b/litecord/blueprints/user/billing_job.py index 3f91072..480b456 100644 --- a/litecord/blueprints/user/billing_job.py +++ b/litecord/blueprints/user/billing_job.py @@ -14,6 +14,8 @@ from litecord.snowflake import snowflake_datetime from litecord.types import MINUTES, HOURS from litecord.enums import UserFlags +from litecord.blueprints.users import mass_user_update + log = Logger(__name__) # how many days until a payment needs @@ -130,10 +132,8 @@ async def _process_subscription(app, subscription_id: int): WHERE id = $3 """, first_payment_ts, new_flags, user_id) - user_object = await app.storage.get_user(user_id, secure=True) - - # dispatch updated user to all clients - await app.dispatcher.dispatch_user(user_id, 'USER_UPDATE', user_object) + # dispatch updated user to all possible clients + await mass_user_update(user_id, app) async def payment_job(app): diff --git a/litecord/blueprints/users.py b/litecord/blueprints/users.py index d7bb4be..870d4f8 100644 --- a/litecord/blueprints/users.py +++ b/litecord/blueprints/users.py @@ -19,6 +19,49 @@ from litecord.permissions import base_permissions bp = Blueprint('user', __name__) +async def mass_user_update(user_id, app_=None): + """Dispatch USER_UPDATE in a mass way.""" + if app_ is None: + app_ = app + + # by using dispatch_with_filter + # we're guaranteeing all shards will get + # a USER_UPDATE once and not any others. + + session_ids = [] + + public_user = await app_.storage.get_user(user_id) + private_user = await app_.storage.get_user(user_id, secure=True) + + session_ids.extend( + await app_.dispatcher.dispatch_user( + user_id, 'USER_UPDATE', private_user) + ) + + guild_ids = await app_.user_storage.get_user_guilds(user_id) + friend_ids = await app_.user_storage.get_friend_ids(user_id) + + session_ids.extend( + await app_.dispatcher.dispatch_many_filter_list( + 'guild', guild_ids, session_ids, + 'USER_UPDATE', public_user + ) + ) + + session_ids.extend( + await app_.dispatcher.dispatch_many_filter_list( + 'friend', friend_ids, session_ids, + 'USER_UPDATE', public_user + ) + ) + + await app_.dispatcher.dispatch_many( + 'lazy_guild', guild_ids, 'update_user', user_id + ) + + return private_user + + @bp.route('/@me', methods=['GET']) async def get_me(): """Get the current user's information.""" @@ -215,39 +258,7 @@ async def patch_me(): user.pop('password_hash') - public_user = await app.storage.get_user(user_id) - private_user = await app.storage.get_user(user_id, secure=True) - session_ids = [] - - # by using dispatch_with_filter - # we're guaranteeing all shards will get - # a USER_UPDATE once and not any others. - session_ids.extend( - await app.dispatcher.dispatch_user( - user_id, 'USER_UPDATE', private_user) - ) - - guild_ids = await app.user_storage.get_user_guilds(user_id) - friend_ids = await app.user_storage.get_friend_ids(user_id) - - session_ids.extend( - await app.dispatcher.dispatch_many_filter_list( - 'guild', guild_ids, session_ids, - 'USER_UPDATE', public_user - ) - ) - - session_ids.extend( - await app.dispatcher.dispatch_many_filter_list( - 'friend', friend_ids, session_ids, - 'USER_UPDATE', public_user - ) - ) - - await app.dispatcher.dispatch_many( - 'lazy_guild', guild_ids, 'update_user', user_id - ) - + private_user = await mass_user_update(user_id, app) return jsonify(private_user)