Exemplo n.º 1
0
	def invite_user(self, message):
		room_id = message[VarNames.ROOM_ID]
		if room_id not in self.channels:
			raise ValidationError("Access denied, only allowed for channels {}".format(self.channels))
		room = Room.objects.get(id=room_id)
		if room.is_private:
			raise ValidationError("You can't add users to direct room, create a new room instead")
		users = message.get(VarNames.ROOM_USERS)
		users_in_room = list(RoomUsers.objects.filter(room_id=room_id).values_list('user_id', flat=True))
		intersect = set(users_in_room) & set(users)
		if bool(intersect):
			raise ValidationError("Users %s are already in the room", intersect)
		users_in_room.extend(users)

		max_id = Message.objects.filter(room_id=room_id).aggregate(Max('id'))['id__max']
		if not max_id:
			max_id = Message.objects.all().aggregate(Max('id'))['id__max']
		ru = [RoomUsers(
			user_id=user_id,
			room_id=room_id,
			last_read_message_id=max_id,
			volume=1,
			notifications=False
		) for user_id in users]
		RoomUsers.objects.bulk_create(ru)

		add_invitee = {
			VarNames.EVENT: Actions.ADD_INVITE,
			VarNames.ROOM_ID: room_id,
			VarNames.ROOM_USERS: users_in_room,
			VarNames.ROOM_NAME: room.name,
			VarNames.INVITEE_USER_ID: users,
			VarNames.INVITER_USER_ID: self.user_id,
			VarNames.HANDLER_NAME: HandlerNames.ROOM,
			VarNames.TIME: get_milliseconds(),
			VarNames.VOLUME: 1,
			VarNames.NOTIFICATIONS: False,
		}
		add_invitee_dumped = encode_message(add_invitee, True)
		for user in users:
			self.raw_publish(add_invitee_dumped, RedisPrefix.generate_user(user))

		invite = {
			VarNames.EVENT: Actions.INVITE_USER,
			VarNames.ROOM_ID: room_id,
			VarNames.INVITEE_USER_ID: users,
			VarNames.INVITER_USER_ID: self.user_id,
			VarNames.HANDLER_NAME: HandlerNames.ROOM,
			VarNames.ROOM_USERS: users_in_room,
			VarNames.TIME: get_milliseconds(),
			VarNames.CB_BY_SENDER: self.id,
			VarNames.JS_MESSAGE_ID: message[VarNames.JS_MESSAGE_ID]
		}
		self.publish(invite, room_id, True)
Exemplo n.º 2
0
	def save_channels_settings(self, message):
		channel_id = message[VarNames.CHANNEL_ID]
		channel_name = message[VarNames.CHANNEL_NAME]
		new_creator = message[VarNames.CHANNEL_CREATOR_ID]
		if not channel_name or len(channel_name) > 16:
			raise ValidationError('Incorrect channel name name "{}"'.format(channel_name))
		channel = Channel.objects.get(id=channel_id)
		users_id = list(RoomUsers.objects.filter(room__channel_id=channel_id).values_list('user_id', flat=True))
		if channel.creator_id != self.user_id and self.user_id not in users_id:
			raise ValidationError("You are not allowed to edit this channel")
		if new_creator != channel.creator_id:
			if self.user_id != channel.creator_id:
				raise ValidationError("Only admin can change the admin of this channel")
			if new_creator not in users_id:
				raise ValidationError("You can only change admin to one of the users in this channels room")
			channel.creator_id = new_creator
		if self.user_id not in users_id: # if channel has no rooms
			users_id.append(self.user_id)
		channel.name = channel_name
		channel.save()
		m = {
			VarNames.EVENT: Actions.SAVE_CHANNEL_SETTINGS,
			VarNames.CHANNEL_ID: channel_id,
			VarNames.CB_BY_SENDER: self.id,
			VarNames.HANDLER_NAME: HandlerNames.ROOM,
			VarNames.CHANNEL_NAME: channel_name,
			VarNames.CHANNEL_CREATOR_ID: channel.creator_id,
			VarNames.TIME: get_milliseconds(),
			VarNames.JS_MESSAGE_ID: message[VarNames.JS_MESSAGE_ID],
		}
		for user_id in users_id:
			self.publish(m, RedisPrefix.generate_user(user_id))
Exemplo n.º 3
0
    def delete_channel(self, message):
        channel_id = message[VarNames.CHANNEL_ID]
        channel = Channel.objects.get(id=channel_id)
        if channel.creator_id != self.user_id:
            raise ValidationError(
                f"Only admin can delete this channel. Please ask ${User.objects.get(id=channel.creator_id).username}"
            )
        # if Room.objects.filter(channel_id=channel_id).count() > 0:
        users_id = list(
            RoomUsers.objects.filter(room__channel_id=channel_id).values_list(
                'user_id', flat=True))
        if len(users_id) > 0:
            raise ValidationError(
                f"Some users are still in the rooms on this channel Please ask them to leave"
            )
        Room.objects.filter(channel_id=channel_id).update(disabled=True)
        channel.disabled = True
        channel.save()

        message = {
            VarNames.EVENT: Actions.DELETE_CHANNEL,
            VarNames.CHANNEL_ID: channel_id,
            VarNames.HANDLER_NAME: HandlerNames.CHANNELS,
            VarNames.TIME: get_milliseconds(),
            VarNames.CB_BY_SENDER: self.id,
            VarNames.JS_MESSAGE_ID: message[VarNames.JS_MESSAGE_ID]
        }
        self.publish(message, self.channel)
Exemplo n.º 4
0
 def set_connection_id(js_message_id, connection_id):
     return {
         VarNames.EVENT: Actions.SET_WEBRTC_ID,
         VarNames.HANDLER_NAME: HandlerNames.NULL,
         VarNames.CONNECTION_ID: connection_id,
         VarNames.JS_MESSAGE_ID: js_message_id,
         VarNames.TIME: get_milliseconds(),
     }
Exemplo n.º 5
0
def validate_edit_message(self_id, message):
    if message.sender_id != self_id:
        raise ValidationError("You can only edit your messages")
    if message.time + ONE_DAY < get_milliseconds():
        raise ValidationError(
            "You can only edit messages that were send not more than 1 day")
    if message.deleted:
        raise ValidationError("Already deleted")
Exemplo n.º 6
0
	def unsubscribe_direct_message(self, room_id):
		return {
			VarNames.EVENT: Actions.DELETE_ROOM,
			VarNames.ROOM_ID: room_id,
			VarNames.USER_ID: self.user_id,
			HandlerNames.NAME: HandlerNames.CHANNELS,
			VarNames.TIME: get_milliseconds()
		}
Exemplo n.º 7
0
		def edit_glyphy(message, giphy):
			Message.objects.filter(id=message.id).update(
				content=message.content,
				symbol=message.symbol,
				giphy=giphy,
				edited_times=get_milliseconds()
			)
			message.giphy = giphy
			self.publish(self.message_creator.create_send_message(message, Actions.EDIT_MESSAGE, None, {}), message.room_id)
Exemplo n.º 8
0
	def default(self, content, event, handler):
		"""
		:return: {"action": event, "content": content, "time": "20:48:57"}
		"""
		return {
			VarNames.EVENT: event,
			VarNames.CONTENT: content,
			VarNames.USER_ID: self.user_id,
			VarNames.TIME: get_milliseconds(),
			HandlerNames.NAME: handler
		}
Exemplo n.º 9
0
	def set_room(self, rooms, users, online, up):
		return {
			VarNames.ROOM_USERS: users,
			VarNames.ONLINE: online,
			VarNames.ROOMS: rooms,
			VarNames.HANDLER_NAME: HandlerNames.WS,
			VarNames.EVENT: Actions.SET_WS_ID,
			VarNames.WEBRTC_OPPONENT_ID: self.id,
			VarNames.TIME: get_milliseconds(),
			VarNames.USER_IMAGE: up.photo.url if up.photo else None,
			VarNames.CURRENT_USER_SETTINGS: self.get_user_settings(up),
			VarNames.CURRENT_USER_INFO: self.get_user_profile(up),
		}
Exemplo n.º 10
0
    def offer_webrtc(self, content, connection_id, room_id, action):
        """
		:return: {"action": "call", "content": content, "time": "20:48:57"}
		"""
        return {
            VarNames.EVENT: action,
            VarNames.CONTENT: content,
            VarNames.USER_ID: self.user_id,
            VarNames.HANDLER_NAME: HandlerNames.WEBRTC,
            VarNames.CONNECTION_ID: connection_id,
            VarNames.WEBRTC_OPPONENT_ID: self.id,
            VarNames.ROOM_ID: room_id,
            VarNames.TIME: get_milliseconds()
        }
Exemplo n.º 11
0
	def sync_history(self, in_message):
		room_ids = in_message[VarNames.ROOM_IDS]
		message_ids = in_message[VarNames.MESSAGE_IDS]
		if not set(room_ids).issubset(self.channels):
			raise ValidationError("This is not a messages in the room you are in")

		messages = Message.objects.filter(
			Q(room_id__in=room_ids)
			& ~Q(id__in=message_ids)
			& Q(edited_times__gt=get_milliseconds() - in_message[VarNames.LAST_SYNCED])
		)
		content = MessagesCreator.message_models_to_dtos(messages)
		self.ws_write({
			VarNames.CONTENT: content,
			VarNames.JS_MESSAGE_ID: in_message[VarNames.JS_MESSAGE_ID],
			VarNames.HANDLER_NAME: HandlerNames.NULL
		})
Exemplo n.º 12
0
	def edit_message(self, data):
		message_id = data[VarNames.MESSAGE_ID]
		message = Message.objects.get(id=message_id)
		if message.sender_id != self.user_id:
			raise ValidationError("You can only edit your messages")
		if message.time + 60000 < get_milliseconds():
			raise ValidationError("You can only edit messages that were send not more than 1 min ago")
		if message.deleted:
			raise ValidationError("Already deleted")
		message.content = data[VarNames.CONTENT]
		selector = Message.objects.filter(id=message_id)
		if message.content is None:
			selector.update(deleted=True)
			action = Actions.DELETE_MESSAGE
		else:
			action = Actions.EDIT_MESSAGE
			selector.update(content=message.content)
		self.publish(self.create_send_message(message, action), message.room_id)
Exemplo n.º 13
0
	def edit_message(self, data):
		message = Message.objects.get(id=data[VarNames.MESSAGE_ID])
		validate_edit_message(self.user_id, message)
		message.content = data[VarNames.CONTENT]
		MessageHistory(message=message, content=message.content, giphy=message.giphy).save()
		message.edited_times += 1
		giphy_match = self.isGiphy(data[VarNames.CONTENT])
		if message.content is None:
			Message.objects.filter(id=data[VarNames.MESSAGE_ID]).update(
				deleted=True,
				edited_times=get_milliseconds(),
				content=None
			)
			self.publish(self.message_creator.create_send_message(message, Actions.DELETE_MESSAGE, None, {}), message.room_id)
		elif giphy_match is not None:
			self.edit_message_giphy(giphy_match, message)
		else:
			self.edit_message_edit(data, message)
Exemplo n.º 14
0
 def on_close(self):
     if self.async_redis.subscribed:
         self.logger.info("Close event, unsubscribing from %s",
                          self.channels)
         self.async_redis.unsubscribe(self.channels)
     else:
         self.logger.info("Close event, not subscribed, channels: %s",
                          self.channels)
     self.async_redis_publisher.srem(RedisPrefix.ONLINE_VAR, self.id)
     online = self.get_dict_users_from_redis()
     my_online = online.setdefault(self.user_id, [])
     if self.id in my_online:
         my_online.remove(self.id)
     if self.connected:
         message = self.message_creator.room_online_logout(online)
         self.publish(message, settings.ALL_ROOM_ID)
         UserProfile.objects.filter(id=self.user_id).update(
             last_time_online=get_milliseconds())
     self.disconnect()
Exemplo n.º 15
0
	def create_new_channel(self, message):
		channel_name = message.get(VarNames.CHANNEL_NAME)
		if not channel_name or len(channel_name) > 16:
			raise ValidationError('Incorrect channel name name "{}"'.format(channel_name))

		channel = Channel(name=channel_name, creator_id=self.user_id)
		channel.save()
		channel_id = channel.id
		m = {
			VarNames.EVENT: Actions.CREATE_CHANNEL,
			VarNames.CHANNEL_ID: channel_id,
			VarNames.CHANNEL_CREATOR_ID: channel.creator_id,
			VarNames.CB_BY_SENDER: self.id,
			VarNames.HANDLER_NAME: HandlerNames.ROOM,
			VarNames.CHANNEL_NAME: channel_name,
			VarNames.TIME: get_milliseconds(),
			VarNames.JS_MESSAGE_ID: message[VarNames.JS_MESSAGE_ID],
		}
		self.publish(m, self.channel)
Exemplo n.º 16
0
def no_history_q(q_objects, room_id, h, f):
    q_objects.add(
        Q(room_id=room_id) &
        ((Q(id__gte=h) & Q(id__lte=f) & Q(edited_times__gt=0)
          & Q(time__gt=get_milliseconds() - ONE_DAY)) | Q(id__gt=f)), Q.OR)
Exemplo n.º 17
0
    def save_room_settings(self, message):
        """
		POST only, validates email during registration
		"""
        room_id = message[VarNames.ROOM_ID]
        room_name = message[VarNames.ROOM_NAME]
        creator_id = message.get(
            VarNames.ROOM_CREATOR_ID)  # will be none for private room
        updated = RoomUsers.objects.filter(
            room_id=room_id, user_id=self.user_id).update(
                volume=message[VarNames.VOLUME],
                notifications=message[VarNames.NOTIFICATIONS])
        if updated != 1:
            raise ValidationError("You don't have access to this room")
        room = Room.objects.get(id=room_id)
        update_all = False
        if not room.name:
            if room.p2p != message[VarNames.P2P]:
                room.p2p = message[VarNames.P2P]
                update_all = True
        elif room_id != settings.ALL_ROOM_ID:
            if room_name != room.name:
                room.name = room_name
                update_all = True

            if room.channel_id != message[VarNames.CHANNEL_ID]:
                room.channel_id = message[VarNames.CHANNEL_ID]
                if room.channel_id and room.channel_id not in self.get_users_channels_ids(
                ):
                    raise ValidationError(
                        "You don't have access to this channel")
                update_all = True
            if creator_id != room.creator_id:
                if room.creator_id != self.user_id:
                    raise ValidationError(
                        "Only an owner of this room can change its admin")
                users_id = RoomUsers.objects.filter(
                    room_id=room.id).values_list('user_id', flat=True)
                if creator_id not in users_id:
                    raise ValidationError(
                        "You can only change admin to one of the users in this channels room"
                    )
                room.creator_id = creator_id
                update_all = True
        if message.get(VarNames.CHANNEL_ID):  # will be nOne for private room
            channel = Channel.objects.get(id=message[VarNames.CHANNEL_ID])
            channel_name = channel.name
            channel_creator_id = channel.creator_id
        else:
            channel_name = None
            channel_creator_id = None
        if update_all:
            room.save()
            room_users = list(RoomUsers.objects.filter(room_id=room_id))
            for room_user in room_users:
                self.publish(
                    {
                        VarNames.EVENT: Actions.SAVE_ROOM_SETTINGS,
                        VarNames.CHANNEL_ID: room.channel_id,
                        VarNames.CB_BY_SENDER: self.id,
                        VarNames.HANDLER_NAME: HandlerNames.CHANNELS,
                        VarNames.CHANNEL_NAME: channel_name,
                        VarNames.CHANNEL_CREATOR_ID: channel_creator_id,
                        VarNames.ROOM_CREATOR_ID: room.creator_id,
                        VarNames.ROOM_ID: room.id,
                        VarNames.VOLUME: room_user.volume,
                        VarNames.NOTIFICATIONS: room_user.notifications,
                        VarNames.P2P: message[VarNames.P2P],
                        VarNames.ROOM_NAME: room_name,
                        VarNames.TIME: get_milliseconds(),
                        VarNames.JS_MESSAGE_ID:
                        message[VarNames.JS_MESSAGE_ID],
                    }, RedisPrefix.generate_user(room_user.user_id))
        else:
            self.publish(
                {
                    VarNames.EVENT: Actions.SAVE_ROOM_SETTINGS,
                    VarNames.CHANNEL_ID: room.channel_id,
                    VarNames.CB_BY_SENDER: self.id,
                    VarNames.CHANNEL_CREATOR_ID: channel_creator_id,
                    VarNames.ROOM_CREATOR_ID: room.creator_id,
                    VarNames.HANDLER_NAME: HandlerNames.CHANNELS,
                    VarNames.CHANNEL_NAME: channel_name,
                    VarNames.ROOM_ID: room.id,
                    VarNames.VOLUME: message[VarNames.VOLUME],
                    VarNames.NOTIFICATIONS: message[VarNames.NOTIFICATIONS],
                    VarNames.P2P: message[VarNames.P2P],
                    VarNames.ROOM_NAME: room_name,
                    VarNames.TIME: get_milliseconds(),
                    VarNames.JS_MESSAGE_ID: message[VarNames.JS_MESSAGE_ID],
                }, self.channel)
Exemplo n.º 18
0
    def create_new_room(self, message):
        room_name = message.get(VarNames.ROOM_NAME)
        users = message.get(VarNames.ROOM_USERS)
        channel_id = message.get(VarNames.CHANNEL_ID)
        users.append(self.user_id)
        users = list(set(users))
        if room_name and len(room_name) > 16:
            raise ValidationError('Incorrect room name "{}"'.format(room_name))
        create_room = True
        if not room_name and len(users) == 2:
            user_rooms = evaluate(
                Room.users.through.objects.filter(
                    user_id=self.user_id,
                    room__name__isnull=True).values('room_id'))
            user_id = users[0] if users[1] == self.user_id else users[1]
            try:
                room = RoomUsers.objects.filter(user_id=user_id,
                                                room__in=user_rooms).values(
                                                    'room__id',
                                                    'room__disabled').get()
                room_id = room['room__id']
                if room['room__disabled']:  # only a private room can be disabled
                    Room.objects.filter(id=room_id).update(
                        disabled=False, p2p=message[VarNames.P2P])
                    RoomUsers.objects.filter(
                        user_id=self.user_id, room_id=room_id).update(
                            volume=message[VarNames.VOLUME],
                            notifications=message[VarNames.NOTIFICATIONS])
                else:
                    raise ValidationError('This room already exist')
                create_room = False
            except RoomUsers.DoesNotExist:
                pass
        elif not room_name:
            raise ValidationError(
                'At least one user should be selected, or room should be public'
            )

        if channel_id and channel_id not in self.get_users_channels_ids():
            raise ValidationError("You don't have access to this channel")
        if channel_id:
            channel = Channel.objects.get(id=channel_id)
            channel_name = channel.name
            channel_creator_id = channel.creator_id
        else:
            channel_name = None
            channel_creator_id = None
        if create_room:
            room = Room(name=room_name,
                        channel_id=channel_id,
                        p2p=message[VarNames.P2P])
            if not room_name:
                room.creator_id = self.user_id
            room.save()
            room_id = room.id
            max_id = Message.objects.all().aggregate(Max('id'))['id__max']
            ru = [
                RoomUsers(user_id=user_id,
                          room_id=room_id,
                          last_read_message_id=max_id,
                          volume=message[VarNames.VOLUME],
                          notifications=message[VarNames.NOTIFICATIONS])
                for user_id in users
            ]
            RoomUsers.objects.bulk_create(ru)

        m = {
            VarNames.EVENT: Actions.CREATE_ROOM,
            VarNames.ROOM_ID: room_id,
            VarNames.ROOM_USERS: users,
            VarNames.CB_BY_SENDER: self.id,
            VarNames.INVITER_USER_ID: self.user_id,
            VarNames.HANDLER_NAME: HandlerNames.CHANNELS,
            VarNames.VOLUME: message[VarNames.VOLUME],
            VarNames.P2P: message[VarNames.P2P],
            VarNames.NOTIFICATIONS: message[VarNames.NOTIFICATIONS],
            VarNames.ROOM_NAME: room_name,
            VarNames.TIME: get_milliseconds(),
            VarNames.JS_MESSAGE_ID: message[VarNames.JS_MESSAGE_ID],
        }
        if channel_id:
            m[VarNames.CHANNEL_NAME] = channel_name
            m[VarNames.CHANNEL_ID] = channel_id
            m[VarNames.CHANNEL_CREATOR_ID] = channel_creator_id
        jsoned_mess = encode_message(m, True)
        for user in users:
            self.raw_publish(jsoned_mess, RedisPrefix.generate_user(user))
Exemplo n.º 19
0
    def create_new_room(self, message):
        room_name = message.get(VarNames.ROOM_NAME)
        users = message.get(VarNames.ROOM_USERS)
        users.append(self.user_id)
        users = list(set(users))
        if room_name and len(room_name) > 16:
            raise ValidationError('Incorrect room name "{}"'.format(room_name))
        create_user_rooms = True
        if not room_name and len(users) == 2:
            user_rooms = evaluate(
                Room.users.through.objects.filter(
                    user_id=self.user_id,
                    room__name__isnull=True).values('room_id'))
            user_id = users[0] if users[1] == self.user_id else users[1]
            try:
                room = RoomUsers.objects.filter(user_id=user_id,
                                                room__in=user_rooms).values(
                                                    'room__id',
                                                    'room__disabled').get()
                room_id = room['room__id']
                if room['room__disabled']:
                    Room.objects.filter(id=room_id).update(disabled=False)
                else:
                    raise ValidationError('This room already exist')
                create_user_rooms = False
            except RoomUsers.DoesNotExist:
                pass
        elif not room_name:
            raise ValidationError(
                'At least one user should be selected, or room should be public'
            )
        if create_user_rooms:
            room = Room(name=room_name)
            do_db(room.save)
            room_id = room.id
            max_id = Message.objects.all().aggregate(Max('id'))['id__max']
            ru = [
                RoomUsers(user_id=user_id,
                          room_id=room_id,
                          last_read_message_id=max_id,
                          volume=message[VarNames.VOLUME],
                          notifications=message[VarNames.NOTIFICATIONS])
                for user_id in users
            ]
            RoomUsers.objects.bulk_create(ru)

        m = {
            VarNames.EVENT: Actions.CREATE_ROOM_CHANNEL,
            VarNames.ROOM_ID: room_id,
            VarNames.ROOM_USERS: users,
            VarNames.CB_BY_SENDER: self.id,
            VarNames.INVITER_USER_ID: self.user_id,
            VarNames.HANDLER_NAME: HandlerNames.CHANNELS,
            VarNames.VOLUME: message[VarNames.VOLUME],
            VarNames.NOTIFICATIONS: message[VarNames.NOTIFICATIONS],
            VarNames.ROOM_NAME: room_name,
            VarNames.TIME: get_milliseconds(),
            VarNames.JS_MESSAGE_ID: message[VarNames.JS_MESSAGE_ID],
        }
        jsoned_mess = encode_message(m, True)
        for user in users:
            self.raw_publish(jsoned_mess, RedisPrefix.generate_user(user))
Exemplo n.º 20
0
def ping_online():
    message = encode_message(MessagesCreator.ping_client(get_milliseconds()),
                             True)
    logger.info("Pinging clients: %s", message)
    async_redis_publisher.publish(ALL_ROOM_ID, message)
Exemplo n.º 21
0
	def edit_message_edit(self, data, message):
		action = Actions.EDIT_MESSAGE
		message.giphy = None
		tags = data[VarNames.MESSAGE_TAGS]
		files = UploadedFile.objects.filter(id__in=data.get(VarNames.FILES), user_id=self.user_id)
		if files or tags:
			update_symbols(files, tags, message)
		if tags:
			db_tags = MessageMention.objects.filter(message_id=message.id)
			update_or_create = []
			update_or_create_dict = {}
			for db_tag in db_tags:
				if tags.get(db_tag.symbol) and tags.get(db_tag.symbol) != db_tag.user_id:
					update_or_create.append(MessageMention(message_id=message.id, symbol=db_tag.symbol, user_id=tags[db_tag.symbol]))
					update_or_create_dict[db_tag.symbol] = True
			if update_or_create:
				MessageMention.objects.bulk_update(update_or_create)
			create_tags = []
			for (k, v) in tags.items():
				if not update_or_create_dict.get(k):
					create_tags.append(MessageMention(message_id=message.id, symbol=k, user_id=v))
			if create_tags:
				MessageMention.objects.bulk_create(create_tags)

		if files:
			up_files_to_img(files, message.id)
		if message.symbol:  # fetch all, including that we just store
			db_images = Image.objects.filter(message_id=message.id)
			prep_files = MessagesCreator.prepare_img_video(db_images, message.id)
		else:
			prep_files = None
		Message.objects.filter(id=message.id).update(content=message.content, symbol=message.symbol, giphy=None, edited_times=get_milliseconds())
		self.publish(self.message_creator.create_send_message(message, action, prep_files, tags), message.room_id)