Exemplo n.º 1
0
    def set_online(user_id: str, user_name: str, image: str = '') -> None:
        was_invisible = utils.user_is_invisible(user_id)
        OnStatusHooks.logger.info(
            'setting user {} ({}) online (was invisible before? {})'.format(
                user_id, user_name, was_invisible))
        environ.env.db.set_user_online(user_id)
        rooms = utils.rooms_for_user(user_id)

        if not was_invisible:
            for room_id in rooms:
                room_name = utils.get_room_name(room_id)
                join_activity = utils.activity_for_user_joined(
                    user_id, user_name, room_id, room_name, image)
                environ.env.emit('gn_user_joined',
                                 join_activity,
                                 room=room_id,
                                 broadcast=True,
                                 include_self=False,
                                 namespace='/ws')
            return

        visible_activity = utils.activity_for_going_visible(user_id)
        for room_id in rooms:
            room_name = utils.get_room_name(room_id)
            join_activity = utils.activity_for_user_joined(
                user_id, user_name, room_id, room_name, image)
            admins_in_room = environ.env.db.get_admins_in_room(
                room_id, user_id)

            if admins_in_room is None or len(admins_in_room) == 0:
                environ.env.emit('gn_user_joined',
                                 join_activity,
                                 room=room_id,
                                 broadcast=True,
                                 include_self=False,
                                 namespace='/ws')
                continue

            users_in_room = utils.get_users_in_room(room_id).copy()
            for user_id_in_room, _ in users_in_room.items():
                if user_id_in_room in admins_in_room:
                    continue
                environ.env.emit('gn_user_joined',
                                 join_activity,
                                 room=user_id_in_room,
                                 broadcast=True,
                                 include_self=False,
                                 namespace='/ws')

            for admin_id in admins_in_room:
                environ.env.emit('gn_user_visible',
                                 visible_activity,
                                 room=admin_id,
                                 broadcast=False,
                                 namespace='/ws')
Exemplo n.º 2
0
    def set_invisible(user_id: str, user_name: str, stage: str) -> None:
        OnStatusHooks.logger.info('setting user {} ({}) to invisible'.format(
            user_id,
            user_name,
        ))

        # when logging in as 'invisible', the rest call can happen after ws
        # logs in, in which case we don't want to update last_online
        if stage == 'login':
            is_offline = True
        else:
            is_offline = not utils.user_is_online(user_id)

        environ.env.db.set_user_invisible(user_id, is_offline=is_offline)

        if is_offline:
            # nothing more to do if offline already
            return

        disconnect_activity = utils.activity_for_disconnect(user_id, user_name)

        rooms = utils.rooms_for_user(user_id)
        for room_id in rooms:
            admins_in_room = environ.env.db.get_admins_in_room(
                room_id, user_id)
            if admins_in_room is None or len(admins_in_room) == 0:
                environ.env.emit('gn_user_disconnected',
                                 disconnect_activity,
                                 room=room_id,
                                 broadcast=True,
                                 include_self=False,
                                 namespace='/ws')
                continue

            users_in_room = utils.get_users_in_room(room_id)
            for other_user_id, _ in users_in_room.items():
                if other_user_id in admins_in_room:
                    continue
                environ.env.emit('gn_user_disconnected',
                                 disconnect_activity,
                                 room=other_user_id,
                                 broadcast=True,
                                 include_self=False,
                                 namespace='/ws')

            invisible_activity = utils.activity_for_going_invisible(user_id)
            for admin_id in admins_in_room:
                environ.env.emit('gn_user_invisible',
                                 invisible_activity,
                                 room=admin_id,
                                 broadcast=False,
                                 namespace='/ws')
Exemplo n.º 3
0
 def set_offline(user_id: str, user_name: str) -> None:
     OnStatusHooks.logger.info('setting user {} ({}) to offline'.format(
         user_id,
         user_name,
     ))
     environ.env.db.set_user_offline(user_id)
     activity_json = utils.activity_for_disconnect(user_id, user_name)
     rooms = utils.rooms_for_user(user_id)
     for room_id in rooms:
         environ.env.emit('gn_user_disconnected',
                          activity_json,
                          room=room_id,
                          broadcast=True,
                          include_self=False,
                          namespace='/ws')
Exemplo n.º 4
0
    def set_invisible(user_id: str, user_name: str) -> None:
        OnStatusHooks.logger.info('setting user {} ({}) to invisible'.format(
            user_id,
            user_name,
        ))

        is_offline = not utils.user_is_online(user_id)
        environ.env.db.set_user_invisible(user_id, is_offline=is_offline)

        if is_offline:
            # nothing more to do if offline already
            return

        disconnect_activity = utils.activity_for_disconnect(user_id, user_name)

        rooms = utils.rooms_for_user(user_id)
        for room_id in rooms:
            admins_in_room = environ.env.db.get_admins_in_room(
                room_id, user_id)
            if admins_in_room is None or len(admins_in_room) == 0:
                environ.env.emit('gn_user_disconnected',
                                 disconnect_activity,
                                 room=room_id,
                                 broadcast=True,
                                 include_self=False,
                                 namespace='/ws')
                continue

            users_in_room = utils.get_users_in_room(room_id)
            for other_user_id, _ in users_in_room.items():
                if other_user_id in admins_in_room:
                    continue
                environ.env.emit('gn_user_disconnected',
                                 disconnect_activity,
                                 room=other_user_id,
                                 broadcast=True,
                                 include_self=False,
                                 namespace='/ws')

            invisible_activity = utils.activity_for_going_invisible(user_id)
            for admin_id in admins_in_room:
                environ.env.emit('gn_user_invisible',
                                 invisible_activity,
                                 room=admin_id,
                                 broadcast=False,
                                 namespace='/ws')
Exemplo n.º 5
0
    def broadcast(arg: tuple) -> None:
        orig_data, activity = arg
        data = {
            'actor': {
                'id': activity.actor.id,
                'displayName': activity.actor.display_name
            },
            'verb': 'update',
            'object': {
                'objectType': 'userInfo',
                'attachments': list()
            },
            'id': activity.id,
            'published': activity.published
        }

        if not hasattr(activity.object, 'attachments') or len(
                activity.object.attachments) == 0:
            logger.warning('empty object.attachments: %s' % str(orig_data))
            return

        user_id = environ.env.session.get(SessionKeys.user_id.value,
                                          activity.actor.id)
        user_name = environ.env.session.get(SessionKeys.user_name.value,
                                            activity.actor.display_name)
        protected_keys = {SessionKeys.user_id.value, SessionKeys.token.value}

        for attachment in activity.object.attachments:
            if attachment.object_type in protected_keys:
                logger.warning(
                    'user "%s" (%s) tried to change protected key "%s", skipping'
                    % attachment.object_type)

            decoded = utils.b64d(attachment.content)
            if attachment.object_type in SessionKeys._member_names_:
                environ.env.session[attachment.object_type] = decoded
            else:
                logger.warning(
                    'key "%s" is not a predefined, not updating session for "%s" (%s), value was "%s"'
                    % (attachment.object_type, user_name, user_id, decoded))

            environ.env.auth.update_session_for_key(user_id,
                                                    attachment.object_type,
                                                    decoded)
            data['object']['attachments'].append({
                'content':
                attachment.content,
                'objectType':
                attachment.object_type,
            })

        logger.info('about to send updated user info: %s' % str(data))
        room_uuid = None
        if hasattr(activity, 'target') and hasattr(activity.target, 'id'):
            target_id = activity.target.id
            if target_id is not None and len(target_id.strip()) > 0:
                room_uuid = target_id

        if room_uuid is not None:
            environ.env.emit('gn_user_info_updated',
                             data,
                             json=True,
                             broadcast=True,
                             room=room_uuid,
                             namespace='/ws')
        else:
            rooms = utils.rooms_for_user(activity.actor.id)
            for room_uuid in rooms:
                data_copy = data.copy()
                data_copy['target'] = {'id': room_uuid}
                environ.env.emit('gn_user_info_updated',
                                 data,
                                 json=True,
                                 broadcast=True,
                                 room=room_uuid,
                                 namespace='/ws')