def _process(self, socket): data = helpers.read_all(socket, self._config.buffer_size) if data: msg = message.deserialize(data) try: action = self._actions[msg.action] action(socket, msg.arguments, msg.token) except KeyError: msg = message.Message() msg.action = message.Actions.SERVER_MESSAGE resp = models.Response() resp.error = True resp.error_code = message.ErrorCodes.UNKNOWN_ACTION resp.message = "Unknown action." msg.arguments = resp self._try_send(socket, message.serialize(msg)) except Exception as ex: msg = message.Message() msg.action = message.Actions.SERVER_MESSAGE resp = models.Response() resp.error = True resp.error_code = message.ErrorCodes.INTERNAL_SERVER_ERROR resp.message = "Internal server error." msg.arguments = resp self._try_send(socket, message.serialize(msg)) self._logger.exception(ex) else: raise EmptyDataError()
def _open_user_ban_vote(self, socket, model, token=""): """ Opens user ban vote :param socket: socket of the users who want to ban other user :param model: ban model :param token: response token """ resp = message.Message() session = self._connections.get_session(socket) can_ban = socket in self._active_chats.get(model.chat_id) \ and not server.services.chat_service.is_user_admin(model.banned_user_id, model.chat_id) if can_ban: chat = server.services.chat_service.get_chat(model.chat_id) if chat: if self._active_chats.has_key(model.chat_id): vote_key = (model.chat_id, model.banned_user_id) self._active_ban_votes.open_vote( vote_key, self._config.vote_timer, lambda r: (lambda c, u, r: self._close_vote(c, u, r)) (model.chat_id, model.banned_user_id, r)) # fill default votes for all users in chat # default value is False, True is only for user, who suggest ban sockets = self._active_chats.get(model.chat_id) for s in sockets: s_session = self._connections.get_session(s) if session.user_id != model.banned_user_id: self._active_ban_votes.vote( vote_key, s_session.user_id, s_session.user_id == session.user_id) resp.action = message.Actions.USER_BAN_VOTE_IS_OPENED resp_model = models.BanVote() resp_model.chat_id = model.chat_id resp_model.banned_user_id = model.banned_user_id resp_model.initiator_id = session.user_id resp_model.timeout = self._config.vote_timer resp.arguments = resp_model self._broadcast(model.chat_id, resp) else: resp.action = message.Actions.RESPONSE resp_model = models.Response() resp_model.error = True resp_model.message = "Chat wasn't found" resp_model.error_code = message.ErrorCodes.CHAT_NOT_FOUND resp.arguments = resp_model self._try_send(socket, message.serialize(resp)) else: resp.action = message.Actions.RESPONSE resp_model = models.Response() resp_model.error = True resp_model.message = "You don't have permissions to ban this user" resp_model.error_code = message.ErrorCodes.NOT_ENOUGH_PERMISSIONS resp.arguments = resp_model resp.token = token self._try_send(socket, message.serialize(resp))
def _create_chat(self, socket, model, token=""): """ Create new chat :param socket: user's socket :param model: new chat data. Type is models.ChatCreation :param token: response token """ resp = message.Message() resp_model = None valid = True if not model.name: resp.action = message.Actions.RESPONSE resp_model = models.Response() resp_model.error = True resp_model.message = "Chat name cannot be empty string." resp_model.error_code = message.ErrorCodes.INVALID_CHAT_NAME valid = False if valid: session = self._connections.get_session(socket) if session.is_guest and not model.opened: resp.action = message.Actions.RESPONSE resp_model = models.Response() resp_model.error = True resp_model.message = "Only authorized users can create not opened chats" resp_model.error_code = message.ErrorCodes.NOT_ENOUGH_PERMISSIONS valid = False if valid and (not server.services.chat_service.get_chat_by_name( model.name) is None): resp.action = message.Actions.RESPONSE resp_model = models.Response() resp_model.error = True resp_model.message = "Chat with name " + model.name + " already exists" resp_model.error_code = message.ErrorCodes.CHAT_ALREADY_EXISTS valid = False if valid: chat = server.services.chat_service.add_chat( model.name, model.opened, model.private, model.password) if not session.is_guest and not model.opened: server.services.chat_service.add_admin_to_chat( session.user_id, chat.chat_id) resp.action = message.Actions.NEW_CHAT_RESPONSE resp_model = models.ChatResponse() resp_model.error = False resp_model.chat_id = chat.chat_id resp_model.name = chat.name resp_model.opened = chat.opened resp_model.private = chat.private resp.token = token resp.arguments = resp_model self._try_send(socket, message.serialize(resp))
def _make_admin(self, socket, model, token=""): """ Makes user admin of the chat :param model: type is models.UserOfChat :param token: response token """ session = self._connections.get_session(socket) if server.services.chat_service.is_user_admin(session.user_id, model.chat_id) and \ not server.services.chat_service.is_user_admin(model.user_id, model.chat_id): server.services.chat_service.add_admin_to_chat( model.user_id, model.chat_id) server_message = message.Message() server_message.action = message.Actions.USER_WAS_MADE_ADMIN server_message.arguments = model self._broadcast(model.chat_id, server_message) else: resp_model = models.Response() resp_model.error = True resp_model.error_code = message.ErrorCodes.NOT_ENOUGH_PERMISSIONS resp_model.message = "You aren't admin of the chat or user is already admin" resp = message.Message() resp.action = message.Actions.RESPONSE resp.arguments = resp_model resp.token = token self._try_send(resp_model)
def _vote_for_user_ban(self, socket, model, token=""): """ Votes for user ban :param socket: socket of voter :param model: vote model. Type is models.UserChatPair :param token: response token """ if socket in self._active_chats.get(model.chat_id, []): session = self._connections.get_session(socket) self._active_ban_votes.vote((model.chat_id, model.user_id), session.user_id, True, True) msg = message.Message() msg.action = message.Actions.VOTE_FOR_USER_BAN m = models.BanVote() m.chat_id = model.chat_id m.initiator_id = session.user_id m.banned_user_id = model.user_id msg.arguments = m self._broadcast(model.chat_id, msg) else: resp_model = models.Response() resp_model.error = True resp_model.error_code = message.ErrorCodes.NOT_ENOUGH_PERMISSIONS resp_model.message = "You aren't member of the chat" resp = message.Message() resp.action = message.Actions.RESPONSE resp.arguments = resp_model resp.token = token self._try_send(resp_model)
def _send_user_message(self, socket, model, token=""): """ Broadcast user's message :param socket: user's socket :param model: message. Type is models.BaseMessage :param token: response token """ session = self._connections.get_session(socket) if socket in self._active_chats.get(model.chat_id): msg = message.Message() msg.action = message.Actions.USER_MESSAGE resp_model = models.UserMessage() resp_model.chat_id = model.chat_id resp_model.message = model.message resp_model.user_id = session.user_id resp_model.login = session.login resp_model.guest = session.is_guest msg.arguments = resp_model self._broadcast(model.chat_id, msg, socket) else: resp_model = models.Response() resp_model.error = True resp_model.error_code = message.ErrorCodes.NOT_ENOUGH_PERMISSIONS resp_model.message = "You aren't member of the chat." resp = message.Message() resp.action = message.Actions.RESPONSE resp.arguments = resp_model resp.token = token self._try_send(resp_model)
def listen(self, callback): """ Socket listener :param callback: Function that is called when new message is received """ socket_list = [self._client_socket] stop = False while not stop: # Get the list sockets which are readable read_sockets, write_sockets, error_sockets = select.select(socket_list, [], []) if read_sockets: sock = read_sockets[0] # incoming message from remote server data = helpers.read_all(sock, self._config.buffer_size) if data: self._logger.info(data) msg = message.deserialize(data) else: msg = message.Message() msg.action = message.Actions.SERVER_MESSAGE resp = models.Response() resp.error = True resp.error_code = message.ErrorCodes.SERVER_IS_UNAVAILABLE resp.message = "Server is unavailable." msg.arguments = resp # clear opened sockets self._client_socket.close() self._requests.clear() stop = True self._logger.error("Server is unavailable.") try: callback(msg) except Exception as ex: self._logger.exception(ex)
def _try_to_ban_user(self, socket, model, token=""): """ User's ban request :param socket: socket of the users who want to ban other user :param model: ban model :param token: response token """ resp = message.Message() session = self._connections.get_session(socket) admin = server.services.chat_service.is_user_admin( session.user_id, model.chat_id) can_ban = socket in self._active_chats.get(model.chat_id) and \ admin and not server.services.chat_service.is_user_admin(model.banned_user_id, model.chat_id) \ and server.services.user_service.does_user_exist(model.banned_user_id) if can_ban: chat = server.services.chat_service.get_chat(model.chat_id) if chat: self._ban_user(model.chat_id, model.banned_user_id, session.user_id) else: resp.action = message.Actions.RESPONSE resp_model = models.Response() resp_model.error = True resp_model.message = "Chat wasn't found" resp_model.error_code = message.ErrorCodes.CHAT_NOT_FOUND resp.arguments = resp_model resp.token = token self._try_send(socket, message.serialize(resp)) else: resp.action = message.Actions.RESPONSE resp_model = models.Response() resp_model.error = True resp_model.message = "You don't have permissions to ban this user" resp_model.error_code = message.ErrorCodes.NOT_ENOUGH_PERMISSIONS resp.arguments = resp_model resp.token = token self._try_send(socket, message.serialize(resp))