239 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			239 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import sys
 | 
						|
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QTabWidget, QListWidget, QStackedWidget, QCheckBox, QSpinBox, QToolBox, QLineEdit, QTableWidget, QTreeWidget, QCalendarWidget, QMessageBox, QToolBar, QSizePolicy
 | 
						|
from PySide6.QtCore import Qt, QTime, QSize, QRect,QEvent, QThread
 | 
						|
from PySide6.QtGui import QCursor, QFont, QIcon, QImage, QPixmap, QShortcut
 | 
						|
from codes.common import clibs, db_operation
 | 
						|
from codes.common.secure_encrypt import PassCipher
 | 
						|
from codes.ui import main_ui
 | 
						|
 | 
						|
class LoginWindow(QWidget):
 | 
						|
    def __init__(self):
 | 
						|
        super().__init__()
 | 
						|
        self.init_ui()
 | 
						|
        self.setup_slot()
 | 
						|
        self.predos()
 | 
						|
        self.le_username.setFocus()
 | 
						|
 | 
						|
    def init_ui(self):
 | 
						|
        self.setMinimumSize(420, 200)
 | 
						|
        self.setMaximumSize(500, 240)
 | 
						|
        self.resize(480, 200)
 | 
						|
        self.setWindowTitle("登录")
 | 
						|
        self.setWindowIcon(QIcon(f"{clibs.base_path}/assets/media/icon.ico"))
 | 
						|
        self.setFont(QFont("Consolas", 14))
 | 
						|
 | 
						|
        self.layout_outter = QHBoxLayout()
 | 
						|
        self.lb_logo = QLabel()
 | 
						|
        self.lb_logo.setAlignment(Qt.AlignmentFlag.AlignCenter)
 | 
						|
        self.lb_logo.setSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Preferred)
 | 
						|
        self.lb_logo.setPixmap(QPixmap(f"{clibs.base_path}/assets/media/logo.png"))
 | 
						|
        self.lb_logo.setFixedSize(QSize(120, 120))
 | 
						|
        self.lb_logo.setScaledContents(True)
 | 
						|
        self.layout_outter.addWidget(self.lb_logo)
 | 
						|
 | 
						|
        self.tabW_login = QTabWidget()
 | 
						|
        self.tab_login = QWidget()
 | 
						|
        self.tabW_login.addTab(self.tab_login, "登录")
 | 
						|
        self.tab_register = QWidget()
 | 
						|
        self.tabW_login.addTab(self.tab_register, "注册")
 | 
						|
        self.layout_outter.addWidget(self.tabW_login)
 | 
						|
 | 
						|
        # 登陆页面
 | 
						|
        self.layout_H_username = QHBoxLayout()
 | 
						|
        self.lb_username = QLabel("账号")
 | 
						|
        self.lb_username.setAlignment(Qt.AlignmentFlag.AlignCenter)
 | 
						|
        self.layout_H_username.addWidget(self.lb_username)
 | 
						|
        self.le_username = QLineEdit()
 | 
						|
        self.le_username.setFocus()
 | 
						|
        self.layout_H_username.addWidget(self.le_username)
 | 
						|
 | 
						|
        self.layout_H_password = QHBoxLayout()
 | 
						|
        self.lb_password = QLabel("密码")
 | 
						|
        self.lb_password.setAlignment(Qt.AlignmentFlag.AlignCenter)
 | 
						|
        self.layout_H_password.addWidget(self.lb_password)
 | 
						|
        self.le_password = QLineEdit()
 | 
						|
        self.le_password.setEchoMode(QLineEdit.EchoMode.Password)
 | 
						|
        self.layout_H_password.addWidget(self.le_password)
 | 
						|
 | 
						|
        self.layout_H_button = QHBoxLayout()
 | 
						|
        self.btn_login = QPushButton("登录")
 | 
						|
        self.btn_login.setAutoDefault(True)
 | 
						|
        self.btn_cancel = QPushButton("取消")
 | 
						|
        self.btn_cancel.setAutoDefault(True)
 | 
						|
        self.layout_H_button.addWidget(self.btn_login)
 | 
						|
        self.layout_H_button.addWidget(self.btn_cancel)
 | 
						|
 | 
						|
        self.layout_V_user_pass = QVBoxLayout()
 | 
						|
        self.layout_V_user_pass.addLayout(self.layout_H_username)
 | 
						|
        self.layout_V_user_pass.addLayout(self.layout_H_password)
 | 
						|
        self.layout_V_user_pass.addLayout(self.layout_H_button)
 | 
						|
        self.tab_login.setLayout(self.layout_V_user_pass)
 | 
						|
 | 
						|
        # 注册页面
 | 
						|
        self.layout_H_username_reg = QHBoxLayout()
 | 
						|
        self.lb_username_reg = QLabel("账号设定")
 | 
						|
        self.lb_username_reg.setAlignment(Qt.AlignmentFlag.AlignCenter)
 | 
						|
        self.layout_H_username_reg.addWidget(self.lb_username_reg)
 | 
						|
        self.le_username_reg = QLineEdit()
 | 
						|
        self.le_username_reg.setFocus()
 | 
						|
        self.layout_H_username_reg.addWidget(self.le_username_reg)
 | 
						|
 | 
						|
        self.layout_H_password_reg = QHBoxLayout()
 | 
						|
        self.lb_password_reg = QLabel("密码设定")
 | 
						|
        self.lb_password_reg.setAlignment(Qt.AlignmentFlag.AlignCenter)
 | 
						|
        self.layout_H_password_reg.addWidget(self.lb_password_reg)
 | 
						|
        self.le_password_reg = QLineEdit()
 | 
						|
        self.le_password_reg.setEchoMode(QLineEdit.EchoMode.Password)
 | 
						|
        self.layout_H_password_reg.addWidget(self.le_password_reg)
 | 
						|
 | 
						|
        self.layout_H_password_reg_confirm = QHBoxLayout()
 | 
						|
        self.lb_password_reg_confirm = QLabel("密码确认")
 | 
						|
        self.lb_password_reg_confirm.setAlignment(Qt.AlignmentFlag.AlignCenter)
 | 
						|
        self.layout_H_password_reg_confirm.addWidget(self.lb_password_reg_confirm)
 | 
						|
        self.le_password_reg_confirm = QLineEdit()
 | 
						|
        self.le_password_reg_confirm.setEchoMode(QLineEdit.EchoMode.Password)
 | 
						|
        self.layout_H_password_reg_confirm.addWidget(self.le_password_reg_confirm)
 | 
						|
 | 
						|
        self.layout_H_button_reg = QHBoxLayout()
 | 
						|
        self.btn_login_reg = QPushButton("确认")
 | 
						|
        self.btn_login_reg.setAutoDefault(True)
 | 
						|
        self.btn_cancel_reg = QPushButton("取消")
 | 
						|
        self.btn_cancel_reg.setAutoDefault(True)
 | 
						|
        self.layout_H_button_reg.addWidget(self.btn_login_reg)
 | 
						|
        self.layout_H_button_reg.addWidget(self.btn_cancel_reg)
 | 
						|
 | 
						|
        self.layout_V_user_pass_reg = QVBoxLayout()
 | 
						|
        self.layout_V_user_pass_reg.addLayout(self.layout_H_username_reg)
 | 
						|
        self.layout_V_user_pass_reg.addLayout(self.layout_H_password_reg)
 | 
						|
        self.layout_V_user_pass_reg.addLayout(self.layout_H_password_reg_confirm)
 | 
						|
        self.layout_V_user_pass_reg.addLayout(self.layout_H_button_reg)
 | 
						|
        self.tab_register.setLayout(self.layout_V_user_pass_reg)
 | 
						|
 | 
						|
        self.setLayout(self.layout_outter)
 | 
						|
 | 
						|
    def setup_slot(self):
 | 
						|
        self.tabW_login.currentChanged.connect(self.onChange_tabW)
 | 
						|
        self.btn_login.clicked.connect(self.login_check)
 | 
						|
        self.btn_cancel.clicked.connect(self.close)
 | 
						|
        self.btn_login_reg.clicked.connect(self.register_check)
 | 
						|
        self.btn_cancel_reg.clicked.connect(self.close)
 | 
						|
        QShortcut("Esc", self).activated.connect(self.close)
 | 
						|
        self.le_password.returnPressed.connect(self.login_check)
 | 
						|
        self.le_password_reg_confirm.returnPressed.connect(self.register_check)
 | 
						|
 | 
						|
    def predos(self):
 | 
						|
        db_file = clibs.base_path / "assets/database/toolbox.db"
 | 
						|
        if not db_file.exists():
 | 
						|
            db_operation.db_init(db_file)
 | 
						|
 | 
						|
    def onChange_tabW(self):
 | 
						|
        text = self.tabW_login.tabText(self.tabW_login.currentIndex())
 | 
						|
        if text == "登录":
 | 
						|
            self.le_username.clear()
 | 
						|
            self.le_password.clear()
 | 
						|
            self.le_username.setFocus()
 | 
						|
        elif text == "注册":
 | 
						|
            self.le_username_reg.clear()
 | 
						|
            self.le_password_reg.clear()
 | 
						|
            self.le_password_reg_confirm.clear()
 | 
						|
            self.le_username_reg.setFocus()
 | 
						|
        else:
 | 
						|
            raise Exception(f"Unknown TabWidget Name: {text}")
 | 
						|
 | 
						|
    def login_check(self):
 | 
						|
        def login_failed():
 | 
						|
            self.le_username.clear()
 | 
						|
            self.le_password.clear()
 | 
						|
            self.le_username.setFocus()
 | 
						|
            QMessageBox.critical(self, "错误", "账号或密码错误,请重新输入!")
 | 
						|
 | 
						|
        def validate_login():
 | 
						|
            nonlocal username, password
 | 
						|
            conn, cursor = db_operation.db_conn()
 | 
						|
            cursor.execute(f""" SELECT * FROM users where username = "{username}" """)
 | 
						|
            record = cursor.fetchall()
 | 
						|
            if len(record) == 0:
 | 
						|
                login_failed()
 | 
						|
            elif len(record) == 1:
 | 
						|
                keys = ["id", "timestamp", "username", "password", "salt"]
 | 
						|
                login_info = dict(zip(keys, record[0]))
 | 
						|
                salt = PassCipher.gen_salt("@".join([username, password]))
 | 
						|
                cipher = PassCipher(salt)
 | 
						|
                # password_encrypt = cipher.encrypt("@".join([username, password]))
 | 
						|
                # print(f"password_encrypt = {password_encrypt}")
 | 
						|
                # exit()
 | 
						|
                try:
 | 
						|
                    decrypt_password = cipher.decrypt(login_info["password"])
 | 
						|
                    if password != decrypt_password:
 | 
						|
                        login_failed()
 | 
						|
                        return False
 | 
						|
                    else:
 | 
						|
                        self.mainWindow = main_ui.MainWindow()
 | 
						|
                        self.mainWindow.show()
 | 
						|
                        db_operation.db_close(conn, cursor)
 | 
						|
                        clibs.username = username
 | 
						|
                        clibs.password = password
 | 
						|
                        self.close()
 | 
						|
                        return True
 | 
						|
                except ValueError:
 | 
						|
                    login_failed()
 | 
						|
                    return False
 | 
						|
            else:
 | 
						|
                raise Exception(f"username duplicated: {username}")
 | 
						|
 | 
						|
        username = self.le_username.text()
 | 
						|
        password = self.le_password.text()
 | 
						|
 | 
						|
        validate_login()
 | 
						|
 | 
						|
    def register_check(self):
 | 
						|
        def register_failed(flag: int = 0):
 | 
						|
            self.le_username_reg.clear()
 | 
						|
            self.le_password_reg.clear()
 | 
						|
            self.le_password_reg_confirm.clear()
 | 
						|
            self.le_username_reg.setFocus()
 | 
						|
            if flag == 0:
 | 
						|
                QMessageBox.critical(self, "错误", "账号已存在,或两次输入密码不一致,请重新输入!")
 | 
						|
            elif flag == 1:
 | 
						|
                QMessageBox.critical(self, "错误", "密码长度不符合要求,请重新输入!")
 | 
						|
 | 
						|
        def validate_register():
 | 
						|
            nonlocal username, password, password_confirm, record, conn, cursor
 | 
						|
            if password != password_confirm:
 | 
						|
                register_failed()
 | 
						|
                return False
 | 
						|
 | 
						|
            if len(password) < clibs.account["minimum_password_length"]:
 | 
						|
                register_failed(flag=1)
 | 
						|
                return False
 | 
						|
 | 
						|
            if len(record) == 0:
 | 
						|
                salt = PassCipher.gen_salt("@".join([username, password]))
 | 
						|
                cipher = PassCipher(salt)
 | 
						|
                password_encrypted = cipher.encrypt(password)
 | 
						|
                cursor.execute("INSERT INTO users (username, password, salt) VALUES (?, ?, ?)", (username, password_encrypted, salt))
 | 
						|
                QMessageBox.information(self, "成功", "注册成功,切换至登录窗口进行登录!")
 | 
						|
                self.tabW_login.setCurrentIndex(self.tabW_login.indexOf(self.tab_login))
 | 
						|
                return True
 | 
						|
            elif len(record) == 1:
 | 
						|
                register_failed()
 | 
						|
                return False
 | 
						|
            else:
 | 
						|
                raise Exception(f"username duplicated: {username}")
 | 
						|
 | 
						|
        username = self.le_username_reg.text()
 | 
						|
        password = self.le_password_reg.text()
 | 
						|
        password_confirm = self.le_password_reg_confirm.text()
 | 
						|
        conn, cursor = db_operation.db_conn()
 | 
						|
        cursor.execute(f""" SELECT * FROM users where username = "{username}" """)
 | 
						|
        record = cursor.fetchall()
 | 
						|
        validate_register()
 | 
						|
 | 
						|
 | 
						|
if __name__ == '__main__':
 | 
						|
    app = QApplication(sys.argv)
 | 
						|
    window = LoginWindow()
 | 
						|
    window.show()
 | 
						|
    sys.exit(app.exec())
 | 
						|
 |