hyb
2025-05-14 d0eb17acf33f5fc28ad295cb151817225fdac902
增加密码查询工具
增加造数脚本和模版
13 files added
427 ■■■■■ changed files
测试组/脚本/密码查询工具/.idea/.gitignore 8 ●●●●● patch | view | raw | blame | history
测试组/脚本/密码查询工具/.idea/inspectionProfiles/profiles_settings.xml 6 ●●●●● patch | view | raw | blame | history
测试组/脚本/密码查询工具/.idea/misc.xml 7 ●●●●● patch | view | raw | blame | history
测试组/脚本/密码查询工具/.idea/modules.xml 8 ●●●●● patch | view | raw | blame | history
测试组/脚本/密码查询工具/.idea/密码查询工具.iml 10 ●●●●● patch | view | raw | blame | history
测试组/脚本/密码查询工具/database_info.json 32 ●●●●● patch | view | raw | blame | history
测试组/脚本/密码查询工具/main.spec 38 ●●●●● patch | view | raw | blame | history
测试组/脚本/密码查询工具/mimatubiao.png patch | view | raw | blame | history
测试组/脚本/密码查询工具/setup.py 22 ●●●●● patch | view | raw | blame | history
测试组/脚本/密码查询工具/username_history.json 1 ●●●● patch | view | raw | blame | history
测试组/脚本/密码查询工具/密码查询工具.spec 38 ●●●●● patch | view | raw | blame | history
测试组/脚本/密码查询工具/密码查询工具V2.0.py 256 ●●●●● patch | view | raw | blame | history
测试组/脚本/造数脚本 @ 55fe8d 1 ●●●● patch | view | raw | blame | history
测试组/脚本/密码查询工具/.idea/.gitignore
New file
@@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
测试组/脚本/密码查询工具/.idea/inspectionProfiles/profiles_settings.xml
New file
@@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
  <settings>
    <option name="USE_PROJECT_PROFILE" value="false" />
    <version value="1.0" />
  </settings>
</component>
测试组/脚本/密码查询工具/.idea/misc.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="Black">
    <option name="sdkName" value="Python 3.12 (密码查询工具)" />
  </component>
  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (密码查询工具)" project-jdk-type="Python SDK" />
</project>
测试组/脚本/密码查询工具/.idea/modules.xml
New file
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ProjectModuleManager">
    <modules>
      <module fileurl="file://$PROJECT_DIR$/.idea/密码查询工具.iml" filepath="$PROJECT_DIR$/.idea/密码查询工具.iml" />
    </modules>
  </component>
</project>
测试组/脚本/密码查询工具/.idea/密码查询工具.iml
New file
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
  <component name="NewModuleRootManager">
    <content url="file://$MODULE_DIR$">
      <excludeFolder url="file://$MODULE_DIR$/.venv" />
    </content>
    <orderEntry type="inheritedJdk" />
    <orderEntry type="sourceFolder" forTests="false" />
  </component>
</module>
测试组/脚本/密码查询工具/database_info.json
New file
@@ -0,0 +1,32 @@
{
    "\u798f\u5efa\u4e2d\u533b\u836f": {
        "host": "rm-wz92t61c360x07976wo.mysql.rds.aliyuncs.com",
        "port": "3306",
        "user": "dev",
        "password": "Hello@112",
        "db_name": "srps_fjtcm_uat",
        "table_name": "sys_user",
        "username_col": "login_name",
        "password_col": "plain_text"
    },
    "\u5e7f\u5dde\u751f\u7269": {
        "host": "rm-wz97y18i4t16hfsk6qo.mysql.rds.aliyuncs.com",
        "port": "3306",
        "user": "dev",
        "password": "Hello@112",
        "db_name": "srps_gibh",
        "table_name": "sys_user",
        "username_col": "login_name",
        "password_col": "plain_text"
    },
    "\u6e05\u534e\u5927\u5b66": {
        "host": "rm-wz97y18i4t16hfsk6qo.mysql.rds.aliyuncs.com",
        "port": "3306",
        "user": "dev",
        "password": "Hello@112",
        "db_name": "srps3",
        "table_name": "sys_user",
        "username_col": "login_name",
        "password_col": "plain_text"
    }
}
测试组/脚本/密码查询工具/main.spec
New file
@@ -0,0 +1,38 @@
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
    ['main.py'],
    pathex=[],
    binaries=[],
    datas=[],
    hiddenimports=[],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    noarchive=False,
    optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.datas,
    [],
    name='main',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=False,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)
测试组/脚本/密码查询工具/mimatubiao.png
测试组/脚本/密码查询工具/setup.py
New file
@@ -0,0 +1,22 @@
from setuptools import setup
APP = ['密码查询工具.py']  # 替换为你的Python脚本名
DATA_FILES = ['database_info.json']  # 如果你有其他的静态资源文件,添加到这里
OPTIONS = {
    'argv_emulation': True,
    'packages': ['tkinter', 'mysql.connector'],  # 你使用的额外Python包
    'iconfile': 'mimatubiao.png',  # 如果你有自定义图标,替换为图标文件路径
    'plist': {
        'CFBundleName': 'Password Query Tool',
        'CFBundleShortVersionString': '0.1',
        'CFBundleVersion': '0.1',
        'CFBundleIdentifier': 'com.yourcompany.passwordquerytool'
    }
}
setup(
    app=APP,
    data_files=DATA_FILES,
    options={'py2app': OPTIONS},
    setup_requires=['py2app'],
)
测试组/脚本/密码查询工具/username_history.json
New file
@@ -0,0 +1 @@
["gly"]
测试组/脚本/密码查询工具/密码查询工具.spec
New file
@@ -0,0 +1,38 @@
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
    ['密码查询工具.py'],
    pathex=[],
    binaries=[],
    datas=[],
    hiddenimports=[],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    noarchive=False,
    optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.datas,
    [],
    name='密码查询工具',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=False,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)
测试组/脚本/密码查询工具/密码查询工具V2.0.py
New file
@@ -0,0 +1,256 @@
import tkinter as tk
from tkinter import messagebox, simpledialog, ttk
import pymysql
from Crypto.Cipher import AES
import base64
import json
import os
VUE_APP_EncryptPrivateValue = "12345678abcdefgh"
HISTORY_FILE = "username_history.json"
class PasswordQueryApp:
    def __init__(self, root):
        self.root = root
        self.root.title("密码查询工具")
        self.database_info_file = "database_info.json"
        self.database_info = self.load_database_info()
        self.create_maintenance_page()
        self.create_query_page()
        self.update_username_menu()
    def load_database_info(self):
        try:
            with open(self.database_info_file, 'r') as f:
                return json.load(f)
        except FileNotFoundError:
            return {}
    def save_database_info(self):
        with open(self.database_info_file, 'w') as f:
            json.dump(self.database_info, f, indent=4)
    def create_maintenance_page(self):
        maintenance_frame = tk.LabelFrame(self.root, text="数据库信息维护")
        maintenance_frame.pack(fill="both", expand="yes", padx=10, pady=10)
        tk.Label(maintenance_frame, text="单位名称:").grid(row=0, column=0, sticky="w")
        self.unit_name_entry = tk.Entry(maintenance_frame)
        self.unit_name_entry.grid(row=0, column=1, padx=5, pady=5)
        tk.Label(maintenance_frame, text="MySQL 主机:").grid(row=1, column=0, sticky="w")
        self.host_entry = tk.Entry(maintenance_frame)
        self.host_entry.grid(row=1, column=1, padx=5, pady=5)
        tk.Label(maintenance_frame, text="MySQL 端口:").grid(row=2, column=0, sticky="w")
        self.port_entry = tk.Entry(maintenance_frame)
        self.port_entry.grid(row=2, column=1, padx=5, pady=5)
        self.port_entry.insert(0, "3306")
        tk.Label(maintenance_frame, text="MySQL 用户名:").grid(row=3, column=0, sticky="w")
        self.user_entry = tk.Entry(maintenance_frame)
        self.user_entry.grid(row=3, column=1, padx=5, pady=5)
        tk.Label(maintenance_frame, text="MySQL 密码:").grid(row=4, column=0, sticky="w")
        self.password_entry = tk.Entry(maintenance_frame, show="*")
        self.password_entry.grid(row=4, column=1, padx=5, pady=5)
        tk.Label(maintenance_frame, text="数据库名:").grid(row=5, column=0, sticky="w")
        self.db_name_entry = tk.Entry(maintenance_frame)
        self.db_name_entry.grid(row=5, column=1, padx=5, pady=5)
        tk.Label(maintenance_frame, text="用户表名:").grid(row=6, column=0, sticky="w")
        self.table_name_entry = tk.Entry(maintenance_frame)
        self.table_name_entry.grid(row=6, column=1, padx=5, pady=5)
        self.table_name_entry.insert(0, "sys_user")
        tk.Label(maintenance_frame, text="用户名列名:").grid(row=7, column=0, sticky="w")
        self.username_col_entry = tk.Entry(maintenance_frame)
        self.username_col_entry.grid(row=7, column=1, padx=5, pady=5)
        self.username_col_entry.insert(0, "login_name")
        tk.Label(maintenance_frame, text="密码列名:").grid(row=8, column=0, sticky="w")
        self.password_col_entry = tk.Entry(maintenance_frame)
        self.password_col_entry.grid(row=8, column=1, padx=5, pady=5)
        self.password_col_entry.insert(0, "plain_text")
        save_button = tk.Button(maintenance_frame, text="保存信息", command=self.save_database_info_action)
        save_button.grid(row=9, columnspan=2, pady=10)
    def update_username_menu(self):
        history = self.load_history()
        menu = self.username_menu["menu"]
        menu.delete(0, "end")
        for name in history:
            menu.add_command(label=name, command=lambda value=name: self.username_entry.delete(0, tk.END) or self.username_entry.insert(0, value))
    def save_database_info_action(self):
        unit_name = self.unit_name_entry.get().strip()
        if unit_name == "":
            messagebox.showerror("错误", "单位名称为必填项")
            return
        self.database_info[unit_name] = {
            "host": self.host_entry.get().strip(),
            "port": self.port_entry.get().strip(),
            "user": self.user_entry.get().strip(),
            "password": self.password_entry.get().strip() or "",
            "db_name": self.db_name_entry.get().strip(),
            "table_name": self.table_name_entry.get().strip(),
            "username_col": self.username_col_entry.get().strip(),
            "password_col": self.password_col_entry.get().strip()
        }
        self.save_database_info()
        self.update_username_menu()
        messagebox.showinfo("成功", "数据库信息保存成功")
    def create_query_page(self):
        query_frame = tk.LabelFrame(self.root, text="密码查询")
        query_frame.pack(fill="both", expand="yes", padx=10, pady=10)
        tk.Label(query_frame, text="选择单位名称:").grid(row=0, column=0, sticky="w")
        self.unit_name_var = tk.StringVar(value="请选择单位")
        self.unit_name_dropdown = tk.OptionMenu(query_frame, self.unit_name_var, *self.database_info.keys())
        self.unit_name_dropdown.grid(row=0, column=1, padx=5, pady=5)
        tk.Label(query_frame, text="输入用户名:").grid(row=1, column=0, sticky="w")
        self.username_entry = tk.Entry(query_frame)
        self.username_entry.grid(row=1, column=1, padx=5, pady=5)
        query_button = tk.Button(query_frame, text="查询密码", command=self.query_password_action)
        query_button.grid(row=2, columnspan=2, pady=10)
        self.password_var = tk.StringVar()
        tk.Label(query_frame, text="密码:").grid(row=3, column=0, sticky="w")
        self.password_entry_login = tk.Entry(query_frame, textvariable=self.password_var, state="readonly")
        self.password_entry_login.grid(row=3, column=1, padx=5, pady=5)
        copy_button = tk.Button(query_frame, text="复制密码", command=self.copy_password)
        copy_button.grid(row=4, column=0, pady=10)
        reset_button = tk.Button(query_frame, text="重置", command=self.reset_fields)
        reset_button.grid(row=4, column=1, pady=10)
        # 用户名下拉菜单
        tk.Label(query_frame, text="选择用户名:").grid(row=5, column=0, sticky="w")
        self.username_menu_var = tk.StringVar()
        self.username_menu_var.set("选择用户名")
        self.username_menu = tk.OptionMenu(query_frame, self.username_menu_var, *self.load_history())
        self.username_menu.grid(row=5, column=1, padx=5, pady=5)
    def query_password_action(self):
        unit_name = self.unit_name_var.get()
        username = self.username_entry.get().strip()
        if unit_name not in self.database_info:
            messagebox.showerror("错误", "请选择有效的单位名称")
            return
        db_info = self.database_info[unit_name]
        try:
            conn = pymysql.connect(
                host=db_info["host"],
                port=int(db_info["port"]),
                user=db_info["user"],
                password=db_info["password"],
                database=db_info["db_name"]
            )
            cursor = conn.cursor()
            query = f"SELECT {db_info['username_col']}, {db_info['password_col']} FROM {db_info['table_name']} WHERE {db_info['username_col']} = %s"
            cursor.execute(query, (username,))
            result = cursor.fetchone()
            if result:
                username_db, password = result
                if password is not None:
                    decrypted_password = self.decrypt_password(username_db, password)
                    self.password_var.set(decrypted_password)
                else:
                    messagebox.showinfo("未找到", "未找到该用户名对应的密码")
            else:
                messagebox.showinfo("未找到", "未找到该用户名对应的密码")
            cursor.close()
            conn.close()
        except pymysql.MySQLError as err:
            messagebox.showerror("数据库错误", f"错误: {err}")
    def decrypt_password(self, username, password):
        try:
            user_info = self.get_user_info(username)
            if user_info:
                encrypted_password, encryption_key = user_info
                return self.decrypt(encrypted_password, encryption_key)
            else:
                return "用户信息不完整或不存在"
        except Exception as e:
            return f"解密错误: {e}"
    def decrypt(self, encrypted_password, encryption_key):
        try:
            key = encryption_key.encode('utf-8')
            iv = VUE_APP_EncryptPrivateValue.encode('utf-8')
            encrypted_password = base64.b64decode(encrypted_password)
            cipher = AES.new(key, AES.MODE_CBC, iv)
            decrypted = cipher.decrypt(encrypted_password)
            unpadded_text = decrypted.rstrip(b'\0').decode('utf-8')
            return unpadded_text
        except Exception as e:
            return f"解密错误: {e}"
    def get_user_info(self, username):
        unit_name = self.unit_name_var.get()
        if unit_name not in self.database_info:
            return None
        db_info = self.database_info[unit_name]
        try:
            conn = pymysql.connect(
                host=db_info["host"],
                port=int(db_info["port"]),
                user=db_info["user"],
                password=db_info["password"],
                database=db_info["db_name"]
            )
            cursor = conn.cursor()
            cursor.execute(f"SELECT {db_info['username_col']}, {db_info['password_col']} FROM {db_info['table_name']} WHERE {db_info['username_col']} = %s", (username,))
            result = cursor.fetchone()
            conn.close()
            return result
        except pymysql.MySQLError as err:
            messagebox.showerror("数据库错误", f"错误: {err}")
            return None
    def copy_password(self):
        decrypted_password = self.password_var.get()
        if decrypted_password:
            self.root.clipboard_clear()
            self.root.clipboard_append(decrypted_password)
            messagebox.showinfo("复制成功", "密码已复制到剪贴板")
    def reset_fields(self):
        self.username_entry.delete(0, tk.END)
        self.password_var.set("")
        self.unit_name_var.set("请选择单位")
    def load_history(self):
        if os.path.exists(HISTORY_FILE):
            with open(HISTORY_FILE, 'r') as f:
                history = json.load(f)
        else:
            history = []
        return history
    def save_history(self, history):
        with open(HISTORY_FILE, 'w') as f:
            json.dump(history, f)
if __name__ == "__main__":
    root = tk.Tk()
    app = PasswordQueryApp(root)
    root.mainloop()
测试组/脚本/造数脚本
New file
@@ -0,0 +1 @@
Subproject commit 55fe8dcda078836d49890f5f263fd5df17db5296