def start_getting_messages(self): cached_messages = session.query(Message).filter( Message.chat_id == self.current_chat.chat_id).all() if cached_messages: self.on_messages_list_label.hide() self.add_messages(cached_messages, True) self.get_messages_thread.start()
def cache_messages(self, messages): session = db_session.create_session() for m in messages: m.chat_id = self.current_chat.chat_id cached_message = session.query(Message).filter( Message.unix_time == m.unix_time and Message.chat_id == m.chat_id).first() if not cached_message: session.add(m) session.commit()
def decrypt_data(self, data, key, signature, username): from constants import credentials, session, config from data.users import User unpadder = padding.PKCS7(128).unpadder() my_private = serialization.load_pem_private_key(open(hashlib.sha512(bytes(self.credentials["login"], "utf-8")).hexdigest() + ".pem", "rb").read(), password=bytes(self.credentials["password"], "utf-8"), backend=default_backend()) if username == self.credentials["username"]: public_key = my_private.public_key() else: cached_user = session.query(User).filter(User.username == username).first() if cached_user: pub_response = {"status": "OK", "public_key": cached_user.public_key} else: pub_response = self.get_public_key(username) user = User() user.username = username user.public_key = pub_response["public_key"] session.add(user) session.commit() if pub_response["status"] == "OK": public_key = serialization.load_pem_public_key(bytes(pub_response["public_key"], "utf-8"), backend=default_backend()) else: return {"status": "error", "error": "Error getting users public key"} key_iv = my_private.decrypt( bytes.fromhex(key), asymmetric_padding.OAEP( mgf=asymmetric_padding.MGF1(algorithm=hashes.SHA512()), algorithm=hashes.SHA512(), label=None ) ) key = key_iv[:32] iv = key_iv[32:] cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) decryptor = cipher.decryptor() decrypted_data = decryptor.update(bytes.fromhex(data)) + decryptor.finalize() decrypted_data = unpadder.update(decrypted_data) + unpadder.finalize() public_key.verify( bytes.fromhex(signature), hashlib.sha512(decrypted_data).digest(), asymmetric_padding.PSS( mgf=asymmetric_padding.MGF1(hashes.SHA512()), salt_length=asymmetric_padding.PSS.MAX_LENGTH ), hashes.SHA512() ) payload = { "status": "OK", "data": decrypted_data, "sent_by": username, "key": key_iv.hex(), "signature": signature } return payload
def cache_chats(self, chats): session = db_session.create_session() for chat in chats: cached_chat = session.query(Chat).filter(Chat == chat).first() if not cached_chat: chat.last_message = json.dumps(chat.last_message) session.add(chat) elif cached_chat.unix_time != chat.unix_time: cached_chat.unix_time = chat.unix_time cached_chat.last_message = json.dumps(chat.last_message) session.merge(cached_chat) session.commit()
def update_contacts_list(self): result = session.query(Contact).all() self.contacts_list.clear() contacts = list() if result: for contact in result: contacts.append(contact) contact_widget = ContactWidget(contact, session) contact_item = QtWidgets.QListWidgetItem() contact_item.setSizeHint(QtCore.QSize(100, 70)) self.contacts_list.addItem(contact_item) self.contacts_list.setItemWidget(contact_item, contact_widget) else: self.on_list_label.show()
def start_getting_chats(self): cached_chats = session.query(Chat).order_by( Chat.unix_time.desc()).all() for chat in cached_chats: chat_obj = Chat(chat.username, chat.chat_id, chat.last_message, None) image = None self.chats.append(chat_obj) # payload = {"status": "OK", "data": chat.last_message, "type": MessageTypes.Text, "sent_by": "@8025a412", "viewed": True} chat_obj.last_message = json.loads(chat.last_message) chat_widget = ChatWidget(chat_obj, image, credentials["username"]) chat_item = QtWidgets.QListWidgetItem() chat_item.setSizeHint(QtCore.QSize(100, 70)) self.chats_list.addItem(chat_item) self.chats_list.setItemWidget(chat_item, chat_widget) self.get_chats_thread.start()
def signin_finished(self, response): global api, credentials, session, contacts login = self.login_line.text() password = self.password_line.text() if response["status"] == "OK": with open("credentials.json", "w", encoding="utf-8") as f: response["data"]["login"] = login response["data"]["password"] = password json.dump(response["data"], f) api = RocketAPI(login, password) api.credentials = response["data"] credentials = json.load( open("credentials.json", "r", encoding="utf-8")) db_session.global_init(f"""db/{hashlib.sha512(credentials['login']. encode('utf-8')).hexdigest()}.db""") session = db_session.create_session() contacts = session.query(Contact).all() ChatsWindow().show() self.close() else: QtWidgets.QMessageBox.critical(self, "", response["error"])
def update_statuses(self, messages): try: session = db_session.create_session() for n, message in enumerate(messages): cached_message = session.query(Message).filter( Message.unix_time == message.unix_time and Message.chat_id == message.chat_id).first() if cached_message is not None: if cached_message.viewed != message.viewed: self.messages_list.itemWidget( self.messages_list.item(n) ).message_status_label.setPixmap( QtGui.QPixmap("img/message_delivered.png").scaled( 20, 20, transformMode=QtCore.Qt.SmoothTransformation)) cached_message.viewed = message.viewed if cached_message.type == MessageTypes.Document: cached_message.data = message.data session.commit() except Exception as e: logging.warning(e)
def encrypt_data(self, data, username): from constants import session, config from data.users import User cached_user = session.query(User).filter(User.username == username).first() if cached_user: response = {"status": "OK", "public_key": cached_user.public_key} else: response = self.get_public_key(username) if response["status"] == "OK": user = User() user.username = username user.public_key = response["public_key"] session.add(user) session.commit() else: print(response["error"]) return {"status": "error", "error": response["error"]} if response["status"] == "OK": # Pad data padder = padding.PKCS7(128).padder() padded_data = padder.update(data) + padder.finalize() # Define backend and key + iv backend = default_backend() key = os.urandom(32) iv = os.urandom(16) key_iv = key + iv # Encrypt all data cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend) encryptor = cipher.encryptor() encrypted_data = encryptor.update(padded_data) + encryptor.finalize() # Get public key of user users_pub = serialization.load_pem_public_key(bytes(response["public_key"], "utf-8"), backend=default_backend()) # Get your private and public keys my_private = serialization.load_pem_private_key(open(hashlib.sha512(bytes(self.credentials["login"], "utf-8")).hexdigest() + ".pem", "rb").read(), password=bytes(self.credentials["password"], "utf-8"), backend=default_backend()) my_pub = my_private.public_key() # Encrypt keys user_encrypted_key = users_pub.encrypt( key_iv, asymmetric_padding.OAEP( mgf=asymmetric_padding.MGF1(algorithm=hashes.SHA512()), algorithm=hashes.SHA512(), label=None ) ) my_encrypted_key = my_pub.encrypt( key_iv, asymmetric_padding.OAEP( mgf=asymmetric_padding.MGF1(algorithm=hashes.SHA512()), algorithm=hashes.SHA512(), label=None ) ) # Sign hash of data signature = my_private.sign( hashlib.sha512(data).digest(), asymmetric_padding.PSS( mgf=asymmetric_padding.MGF1(hashes.SHA512()), salt_length=asymmetric_padding.PSS.MAX_LENGTH ), hashes.SHA512() ) users_keys = {username: user_encrypted_key.hex(), self.credentials["username"]: my_encrypted_key.hex()} payload = { "status": "OK", "data": encrypted_data.hex(), "signature": signature.hex(), "keys": users_keys } return payload else: return {"status": "error", "error": response["error"]}
def __init__(self, parent=None): super().__init__(parent=parent) self.parent = parent self.resize(800, 576) self.setStyleSheet(f"QLabel {{ color: {config['text_color']} }}") self.centralwidget = QtWidgets.QWidget(self) self.gridLayout = QtWidgets.QGridLayout(self.centralwidget) self.setWindowTitle("Rocket Sender") self.current_chat = None self.messages_list = QtWidgets.QListWidget(self.centralwidget) self.messages_list.setStyleSheet( "QListWidget {border: 1px solid lightgrey}") self.chats_list = QtWidgets.QListWidget(self.centralwidget) self.chats_list.setStyleSheet( "QListWidget::item { border-bottom: 1px solid lightgray; } QListWidget {border: 1px solid lightgrey}" ) self.chats_list.itemClicked.connect(self.chat_selected) self.chats_list.setMinimumWidth(270) self.contacts_list = QtWidgets.QListWidget(self.centralwidget) self.contacts_list.setStyleSheet( "QListWidget::item { border-bottom: 1px solid lightgray; }; QListWidget {border: 1px solid lightgrey}" ) self.contacts_list.itemClicked.connect(self.contact_selected) self.contacts_list.setMinimumWidth(270) self.on_list_label = QtWidgets.QLabel("You have no chats") self.on_list_label.setStyleSheet("color: gray") self.on_list_label.setAlignment(QtCore.Qt.AlignCenter) self.on_list_label.setMinimumWidth(270) self.on_messages_list_label = QtWidgets.QLabel("You have no messages") self.on_messages_list_label.setStyleSheet("color: gray") self.on_messages_list_label.setAlignment(QtCore.Qt.AlignCenter) self.on_messages_list_label.setText("Select a chat") self.obtain_chats = QtCore.QTimer(self) self.obtain_chats.timeout.connect(self.timeout) self.obtain_chats.start(5000) self.loading_label = QtWidgets.QLabel(self.centralwidget) self.loading_label.resize(15, 15) self.loading_label.setAlignment(QtCore.Qt.AlignCenter) self.loading_movie = QtGui.QMovie("img/spinner.gif") self.loading_movie.setScaledSize(QtCore.QSize(30, 30)) self.loading_movie.setCacheMode(QtGui.QMovie.CacheAll) self.loading_movie.setSpeed(100) self.loading_label.setMovie(self.loading_movie) self.create_button = QtWidgets.QPushButton(self.centralwidget) self.create_button.setText("Create") self.create_button.clicked.connect(self.create_button_clicked) self.pin_file_button = QtWidgets.QPushButton(self.centralwidget) self.pin_file_button.setText("+") self.pin_file_button.clicked.connect(self.send_file) self.message_text_edit = GrowingTextEdit() self.message_text_edit.setPlaceholderText("Message") self.message_text_edit.setMinimumHeight(28) self.message_text_edit.signal.connect( self.message_text_edit_key_press_event) self.send_message_button = QtWidgets.QPushButton(self.centralwidget) self.send_message_button.clicked.connect(self.start_sending_message) self.send_message_button.setText("Send") self.current_chat_label = QtWidgets.QLabel() self.current_chat_label.setAlignment(QtCore.Qt.AlignLeft) self.current_chat_label.setStyleSheet( "font-weight: bold; font-size:15px;") self.settings_widget = SettingsWidget() self.buttons_bar = BottomButtonsBar(self) self.get_chats_thread = RocketAPIThread() self.get_chats_thread.function = api.get_user_chats self.get_chats_thread.signal.connect(self.complete_getting_chats) self.loading_movie.start() self.get_chats_thread.start() self.get_messages_thread = RocketAPIThread() self.get_messages_thread.function = api.get_all_messages self.get_messages_thread.signal.connect(self.complete_getting_messages) self.cache_messages_thread = RocketAPIThread() self.cache_messages_thread.function = self.cache_messages self.cache_chats_thread = RocketAPIThread() self.cache_chats_thread.function = self.cache_chats self.send_message_thread = RocketAPIThread() self.send_message_thread.function = api.send_message self.send_message_thread.signal.connect(self.complete_sending_message) self.update_statuses_thread = RocketAPIThread() self.update_statuses_thread.function = self.update_statuses self.upload_file_thread = RocketAPIThread() self.upload_file_thread.function = api.upload_file self.upload_file_thread.signal.connect(self.complete_file_upload) self.chats = session.query(Chat).order_by(Chat.unix_time.desc()).all() self.messages = list() self.message_cache = defaultdict() for message in session.query(Message).order_by( Message.unix_time).all(): if message.chat_id in self.message_cache: self.message_cache[message.chat_id].append(message) else: self.message_cache[message.chat_id] = [message] self.gridLayout.addWidget(self.loading_label, 0, 0, 1, 1, alignment=QtCore.Qt.AlignLeft) self.gridLayout.addWidget(self.create_button, 0, 1, 1, 1) self.gridLayout.addWidget(self.chats_list, 1, 0, 1, 2, alignment=QtCore.Qt.AlignLeft) self.gridLayout.addWidget(self.contacts_list, 1, 0, 1, 2, alignment=QtCore.Qt.AlignLeft) self.gridLayout.addWidget(self.buttons_bar, 2, 0, 1, 2) self.gridLayout.addWidget(self.messages_list, 1, 2, 1, 3) self.gridLayout.addWidget(self.pin_file_button, 2, 2, 1, 1) self.gridLayout.addWidget(self.message_text_edit, 2, 3, 1, 1, alignment=QtCore.Qt.AlignBottom) self.gridLayout.addWidget(self.send_message_button, 2, 4, 1, 1) self.gridLayout.addWidget(self.on_list_label, 1, 0, 1, 2) self.gridLayout.addWidget(self.on_messages_list_label, 1, 2, 1, 3) self.gridLayout.addWidget(self.settings_widget, 1, 0, 1, 2) self.gridLayout.addWidget(self.current_chat_label, 0, 2, 1, 3) self.gridLayout.setRowStretch(1, 2) self.gridLayout.setRowStretch(2, 1) self.gridLayout.setSpacing(5) if self.chats: self.on_list_label.hide() self.contacts_list.hide() self.settings_widget.hide() self.start_getting_chats() self.setCentralWidget(self.centralwidget)