def create_user(self):
     """
     Метод создает подключение к БД, запускает метод верификации данных пользователя,
     если получает в ответ True - пытается записать данные пользователя в БД. При ошибке
     выводит сообщение об ошибке.
     :return: True, если добавление пользователя в БД прошло успешно.
              False, если добавление не удалось
     """
     con = connections.connection()
     cursor = con.cursor()
     try:
         cursor.execute(f"SELECT * "
                        f"FROM users "
                        f"WHERE login=?;", self.login)
         result = cursor.fetchall()
         if len(result):
             return 'User with this login already exists'
         else:
             cursor.execute(
                 f"INSERT INTO messenger.users (login, password, token_number) \
                 VALUES (?, ?, ?);", self.login, self.password, self.token)
             con.commit()
             return 'Successfully registered'
     except Exception as e:
         return f'{e}'
    def verify_data(self):
        con = connections.connection()
        if self.message:
            with con:
                try:
                    cursor = con.cursor()
                    cursor.execute(
                        f"SELECT login "
                        f"FROM users "
                        f"WHERE login=?;", self.receiver)
                    result = cursor.fetchall()[0][0]
                    if not result:
                        return 'receiver error'
                except IndexError:
                    return 'receiver error'
                try:
                    cursor = con.cursor()
                    cursor.execute(
                        f"SELECT login "
                        f"FROM users "
                        f"WHERE token_number=?;", self.token)
                    sender_login = cursor.fetchall()[0][0]
                    if not sender_login:
                        return 'authorization error'
                except IndexError:
                    return 'authorization error'

            return sender_login
Beispiel #3
0
 def get_token(self):
     """
     Метод по полученныму логину получает из БД данные пользователя, проверяет
     наличие в базе логина и соответствие пароля логину и пытается записать в БД
     новый токен для данного пользователя.
     :return: token, при успешном внесении токена в базу
              False при невозможности внесения токена в базу по полученным параметрам
     """
     con = connections.connection()
     with con:
         cursor = con.cursor()
         cursor.execute(
             f"SELECT login, password, user_id FROM messenger.users \
                        WHERE login =?;", self.login)
         result = cursor.fetchall()
         if result and result[0][1] == self.password:
             token = random.randint(1000000, 9999999)
             try:
                 cursor.execute(
                     f"UPDATE messenger.users SET token_number = '{token}' "
                     f"WHERE (user_id = '{result[0][2]}');"
                 )
                 con.commit()
                 return token
             except Exception as e:
                 print(e)
 def __delete_user__(self):
     """
     Метод удаляет пользователя из БД
     :return: True, если удаление прошло успешно, False, если возникла ошибка
     """
     con = connections.connection()
     cursor = con.cursor()
     try:
         cursor.execute(
             f"DELETE FROM messenger.users WHERE (login = '******');")
         con.commit()
         return True
     except Exception as e:
         print(e)
     return False
        def get_messages():
            """
            Выдает клиенту сообщение по его токену из очереди сообщений
            Клиент регулярно посылает POST запрос на этот контроллер, запрашивая новые сообщения для него.
            в этом запросе он передает свой токен (поэтому пост запрос, т.к. токен не должен быть в урле)
            :return: http response (код ответа с сообщением о том успешно ли доставлено сообщение)
            в случае наличия запрашиваемых сообщений в очереди, клиенту вовращается пакет сообщений в виде
             словаря to_receive, ключами которого являются логины пользователей, которые отправили сообщения
             запрашивающему пользователю, а значениями - вложенные словари, ключами которых являются дата-время
             отправки сообщения, а значениями - сами сообщения. Словарь to_receive сериализуется в JSON
            """

            token = request.form["token"]
            con = connections.connection()
            with con:
                cursor = con.cursor()
                cursor.execute(
                    "SELECT login "
                    "FROM users "
                    f"WHERE token_number=?", token)
                # По токену клиент устанавливает свой логин, для запроса сообщений из своей очереди, если токен не
                # валидный, проваливается в ответ 403 и в ссылку на авторизацию
                try:
                    my_login = cursor.fetchall()[0][0]
                except IndexError:
                    return make_response("403 Forbidden", 403)
            if my_login:
                # создаем словарик, в который будем помещать имеющиеся в очереди сообщения
                to_receive = {}

                credentials = pika.PlainCredentials('www', 'pass')
                connection = pika.BlockingConnection(
                    pika.ConnectionParameters(config.rabbit_address,
                                              config.rabbit_port, '/',
                                              credentials))
                channel = connection.channel()

                queue = channel.queue_declare(queue=my_login)

                # количество сообщений в очереди
                count = queue.method.message_count

                # пока сообщения в очереди не кончатся,
                # (а их должно быть немного, так как запросы от клиента будут поступать регулярно)
                # вытаскиваем их из очереди, пишем в БД, заносим в наш словарик для клиента
                while count > 0:
                    method_frame, properties, body = channel.basic_get(
                        my_login)
                    data = json.loads(body)

                    login_sender = data['sender']
                    message = data['message']
                    datetime = data['date']

                    if login_sender in to_receive:
                        to_receive[login_sender].update({datetime: message})
                    else:
                        to_receive.update({login_sender: {datetime: message}})

                    con = connections.connection()
                    with con:
                        cur = con.cursor()
                        cur.execute(
                            f"SELECT user_id "
                            "FROM users "
                            f"WHERE login=?;", login_sender)
                        sender_id = cur.fetchall()[0][0]
                        cur.execute(
                            "SELECT user_id "
                            "FROM users "
                            f"WHERE login=?;", my_login)
                        receiver_id = cur.fetchall()[0][0]
                        cur.execute(
                            "INSERT INTO messages(message, sender_id, receiver_id, send_time) "
                            f"VALUES(?, ?, ?, ?)",
                            (message, sender_id, receiver_id, datetime))
                        con.commit()
                    channel.basic_ack(method_frame.delivery_tag)
                    count -= 1
                channel.close()
                connection.close()

                if len(to_receive):
                    return jsonify(to_receive)
                else:
                    return make_response("204 No Content", 204)
            else:
                return make_response("403 Authorization error", 403)
Beispiel #6
0
        def get_history():
            """
            Функция принимает данные из пост запроса от клиента в виде его токена, логина интересующего его собеседника
            и двух дат, ограничивающих интересующий его период времени переписки, по этим данным из БД извлекается
            набор сообщений для отправки на клиент пользователю
            :return: http response (код ответа с сообщением о том успешно ли доставлено сообщение)
            в случае наличия запрашиваемых сообщений в БД, возвращаются данные в виде списка history_pack,
            состоящего из сообщений, представленных, в свою очередь, в виде списков вида
             [логин_запрашивающего, логин_собеседника, сообщение, дата-время].
            Список history_pack сериализуется в JSON
            """
            # сюда занесем выбранные из базы сообщения
            history_pack = []

            token = request.form["token"]
            interlocutor_login = request.form['interlocutor_login']
            date1 = request.form['date1']
            date2 = request.form['date2']
            verify_message = Verification(token, interlocutor_login)
            if verify_message.verify_data() == 'authorization error':
                return make_response("403 Forbidden", 403)
            elif verify_message.verify_data() == 'receiver error':
                return make_response("404 Receiver Not Found", 404)
            elif verify_message.verify_data():
                requester_login = verify_message.verify_data()
                con = connections.connection()

                # Находим user_id, соответствующие логинам
                with con:
                    cur = con.cursor()
                    cur.execute(f"SELECT user_id "
                                "FROM users "
                                f"WHERE login=?;", requester_login)
                    requester_id = cur.fetchall()[0][0]
                    cur.execute(f"SELECT user_id "
                                "FROM users "
                                f"WHERE login=?;", interlocutor_login)
                    interlocutor_id = cur.fetchall()[0][0]

                date1_format = datetime.datetime.strptime(date1, '%d.%m.%Y %H:%M')
                date2_format = datetime.datetime.strptime(date2, '%d.%m.%Y %H:%M')
                con = connections.connection()
                with con:
                    cursor = con.cursor()
                    cursor.execute("SELECT * "
                                   "FROM messages "
                                   f"WHERE sender_id IN (?, ?)"
                                   f"AND receiver_id IN (?, ?)"
                                   f"AND send_time >= ?"
                                   f"AND send_time <= ?;",
                                   requester_id, interlocutor_id,
                                   requester_id, interlocutor_id, f'{date1_format}', f'{date2_format}')

                    try:
                        messages = cursor.fetchall()
                        if messages:
                            for message in messages:
                                if message[0] != message[1]:
                                    transaction = []
                                    if message[0] == requester_id:
                                        transaction.append(requester_login)
                                    elif message[0] == interlocutor_id:
                                        transaction.append(interlocutor_login)
                                    if message[1] == requester_id:
                                        transaction.append(requester_login)
                                    elif message[1] == interlocutor_id:
                                        transaction.append(interlocutor_login)
                                    transaction.append(message[2])
                                    transaction.append(str(message[3]))
                                    history_pack.append(transaction)
                            return jsonify(history_pack)
                        else:
                            return make_response("204 No Content", 204)
                    except IndexError:
                        return make_response("204 No Content", 204)