IT偷懒小工具-域控用户管理

[复制链接]
214 |10
发表于 2025-10-24 14:50:11 | 显示全部楼层 |阅读模式
在你的工作场景中如何,经常对域用户进行管理,该工具是你的选择之一,可以添加登录到N个域,对N个域进行域用户管理,密码登可以设置保存方便下次使用。
注:该软件可能不符合你单位的安全管理要求,如不符合请勿使用。另外选择保存密码的话是以明文保存的。

下载:https://wwzk.lanzouo.com/i0VKu2r79wpi
密码:4ax8


[Asm]  
  1. import sys
  2. import os
  3. import json
  4. import logging
  5. from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
  6.                              QPushButton, QLabel, QLineEdit, QComboBox, QTableWidget,
  7.                              QTableWidgetItem, QMessageBox, QTabWidget, QFormLayout,
  8.                              QGroupBox, QDialog, QDialogButtonBox, QCheckBox, QHeaderView,
  9.                              QSplitter, QFrame, QFileDialog, QInputDialog)
  10. from PyQt5.QtCore import Qt, QSize
  11. from PyQt5.QtGui import QIcon, QFont, QPixmap
  12. # 添加资源路径处理函数
  13. def resource_path(relative_path):
  14.     """获取资源的绝对路径,兼容开发环境和PyInstaller打包后的环境"""
  15.     try:
  16.         # PyInstaller创建临时文件夹,将路径存储在_MEIPASS中
  17.         base_path = sys._MEIPASS
  18.     except Exception:
  19.         base_path = os.path.abspath(".")
  20.     return os.path.join(base_path, relative_path)
  21. class RewardDialog(QDialog):
  22.     def __init__(self, parent=None):
  23.         super().__init__(parent)
  24.         self.setWindowTitle("赏赞")
  25.         self.resize(400, 450)
  26.         # 创建布局
  27.         layout = QVBoxLayout(self)
  28.         # 加载赏赞图片,使用resource_path函数获取正确路径
  29.         reward_pixmap = QPixmap(resource_path("reward.jpg"))
  30.         if not reward_pixmap.isNull():
  31.             # 调整图片大小
  32.             reward_pixmap = reward_pixmap.scaled(300, 300, Qt.KeepAspectRatio)
  33.             # 创建标签显示图片
  34.             image_label = QLabel()
  35.             image_label.setPixmap(reward_pixmap)
  36.             image_label.setAlignment(Qt.AlignCenter)
  37.             layout.addWidget(image_label)
  38.         else:
  39.             # 图片加载失败时显示错误信息
  40.             error_label = QLabel("无法加载赏赞图片")
  41.             error_label.setAlignment(Qt.AlignCenter)
  42.             layout.addWidget(error_label)
  43.         # 添加文字说明
  44.         text_label = QLabel("您的慷慨是对作者最大的支持")
  45.         text_label.setAlignment(Qt.AlignCenter)
  46.         font = QFont()
  47.         font.setPointSize(12)
  48.         text_label.setFont(font)
  49.         layout.addWidget(text_label)
  50.         # 添加关闭按钮
  51.         button_box = QDialogButtonBox(QDialogButtonBox.Close)
  52.         button_box.rejected.connect(self.reject)
  53.         layout.addWidget(button_box)
  54. from domain_manager import DomainManager, DomainConfig, UserPasswordConfig, DomainUserPasswordConfig
  55. # 配置日志
  56. logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
  57. logger = logging.getLogger('domain_gui')
  58. class LoginDialog(QDialog):
  59.     def __init__(self, parent=None):
  60.         super().__init__(parent)
  61.         self.setWindowTitle("域控制器登录")
  62.         self.resize(400, 250)
  63.         # 创建表单布局
  64.         layout = QVBoxLayout(self)
  65.         form_layout = QFormLayout()
  66.         # 域选择下拉框
  67.         self.domain_combo = QComboBox()
  68.         self.domain_combo.currentIndexChanged.connect(self.on_domain_selected)
  69.         form_layout.addRow("选择域:", self.domain_combo)
  70.         # 服务器地址
  71.         self.server_input = QLineEdit()
  72.         form_layout.addRow("服务器地址:", self.server_input)
  73.         # 域名
  74.         self.domain_input = QLineEdit()
  75.         form_layout.addRow("域名:", self.domain_input)
  76.         # 用户名
  77.         self.username_input = QLineEdit()
  78.         form_layout.addRow("用户名:", self.username_input)
  79.         # 密码
  80.         self.password_input = QLineEdit()
  81.         self.password_input.setEchoMode(QLineEdit.Password)
  82.         form_layout.addRow("密码:", self.password_input)
  83.         # 记住登录信息
  84.         self.remember_checkbox = QCheckBox("记住登录信息")
  85.         # 记住密码
  86.         self.remember_password_checkbox = QCheckBox("记住密码")
  87.         # 创建水平布局来放置复选框
  88.         checkbox_layout = QHBoxLayout()
  89.         checkbox_layout.addWidget(self.remember_checkbox)
  90.         checkbox_layout.addWidget(self.remember_password_checkbox)
  91.         # 添加表单到主布局
  92.         layout.addLayout(form_layout)
  93.         layout.addLayout(checkbox_layout)
  94.         # 添加按钮
  95.         button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
  96.         button_box.accepted.connect(self.accept)
  97.         button_box.rejected.connect(self.reject)
  98.         layout.addWidget(button_box)
  99.         # 加载保存的登录信息
  100.         self.load_saved_login()
  101.     def load_saved_login(self):
  102.         """加载保存的登录信息"""
  103.         try:
  104.             configs = DomainConfig.load_configs()
  105.             self.domain_combo.clear()
  106.             self.domain_combo.addItem("新建域配置...")
  107.             for i, config in enumerate(configs):
  108.                 display_text = f"{config.domain} ({config.server_address})"
  109.                 self.domain_combo.addItem(display_text, config)
  110.             if configs:
  111.                 self.domain_combo.setCurrentIndex(1)  # 选择第一个域配置
  112.                 self.remember_checkbox.setChecked(True)
  113.                 if configs[0].password:
  114.                     self.remember_password_checkbox.setChecked(True)
  115.         except Exception as e:
  116.             logger.error(f"加载登录信息失败: {e}")
  117.     def on_domain_selected(self, index):
  118.         """当选择域时更新表单"""
  119.         if index == 0:  # 新建域配置
  120.             self.server_input.clear()
  121.             self.domain_input.clear()
  122.             self.username_input.clear()
  123.             self.password_input.clear()
  124.             self.remember_checkbox.setChecked(False)
  125.             self.remember_password_checkbox.setChecked(False)
  126.         elif index > 0:
  127.             config = self.domain_combo.currentData()
  128.             if config:
  129.                 self.server_input.setText(config.server_address)
  130.                 self.domain_input.setText(config.domain)
  131.                 self.username_input.setText(config.username)
  132.                 if config.password:
  133.                     self.password_input.setText(config.password)
  134.                     self.remember_password_checkbox.setChecked(True)
  135.     def save_login(self):
  136.         """保存登录信息"""
  137.         if self.remember_checkbox.isChecked():
  138.             configs = DomainConfig.load_configs()
  139.             # 创建新的域配置
  140.             new_config = DomainConfig(
  141.                 self.server_input.text(),
  142.                 self.domain_input.text(),
  143.                 self.username_input.text(),
  144.                 self.password_input.text() if self.remember_password_checkbox.isChecked() else None
  145.             )
  146.             # 检查是否已存在相同的域配置
  147.             exists = False
  148.             for i, config in enumerate(configs):
  149.                 if config.domain == new_config.domain and config.server_address == new_config.server_address:
  150.                     configs[i] = new_config
  151.                     exists = True
  152.                     break
  153.             if not exists:
  154.                 configs.append(new_config)
  155.             # 保存配置
  156.             DomainConfig.save_configs(configs, save_passwords=self.remember_password_checkbox.isChecked())
  157.             logger.info("域控制器登录信息保存成功")
  158.         elif os.path.exists('login_config.json'):
  159.             os.remove('login_config.json')
  160.             logger.info("域控制器登录信息已删除")
  161. class CreateUserDialog(QDialog):
  162.     def __init__(self, organizational_units, parent=None):
  163.         super().__init__(parent)
  164.         self.setWindowTitle("创建新用户")
  165.         self.resize(400, 300)
  166.         # 创建表单布局
  167.         layout = QVBoxLayout(self)
  168.         form_layout = QFormLayout()
  169.         # 尝试加载上次保存的密码
  170.         self.saved_password = None
  171.         try:
  172.             # 获取当前连接的域名
  173.             parent_window = self.parent()
  174.             current_domain = None
  175.             if parent_window and hasattr(parent_window, 'domain_manager') and parent_window.domain_manager:
  176.                 current_domain = parent_window.domain_manager.domain
  177.             if current_domain:
  178.                 # 使用DomainUserPasswordConfig加载特定域的用户密码配置
  179.                 self.saved_password = DomainUserPasswordConfig.get_password_for_domain(current_domain)
  180.             # 如果没有特定域的密码配置,尝试使用通用配置(向后兼容)
  181.             if not self.saved_password:
  182.                 user_password_config = UserPasswordConfig.load_config()
  183.                 if user_password_config.password:
  184.                     self.saved_password = user_password_config.password
  185.         except Exception as e:
  186.             logger.error(f"加载保存的密码失败: {e}")
  187.         # 显示名称
  188.         self.display_name_input = QLineEdit()
  189.         form_layout.addRow("显示名称:", self.display_name_input)
  190.         # 登录账号
  191.         self.username_input = QLineEdit()
  192.         form_layout.addRow("登录账号:", self.username_input)
  193.         # 密码
  194.         self.password_input = QLineEdit()
  195.         self.password_input.setEchoMode(QLineEdit.Password)
  196.         # 如果有保存的密码,自动填充
  197.         if self.saved_password:
  198.             self.password_input.setText(self.saved_password)
  199.         form_layout.addRow("密码:", self.password_input)
  200.         # 确认密码
  201.         self.confirm_password_input = QLineEdit()
  202.         self.confirm_password_input.setEchoMode(QLineEdit.Password)
  203.         # 如果有保存的密码,自动填充确认密码
  204.         if self.saved_password:
  205.             self.confirm_password_input.setText(self.saved_password)
  206.         form_layout.addRow("确认密码:", self.confirm_password_input)
  207.         # 电子邮件
  208.         self.email_input = QLineEdit()
  209.         form_layout.addRow("电子邮件:", self.email_input)
  210.         # 组织单位
  211.         self.ou_combo = QComboBox()
  212.         # 添加提示选项,但不设置实际数据
  213.         self.ou_combo.addItem("请选择组织单位", None)
  214.         for ou in organizational_units:
  215.             self.ou_combo.addItem(ou['name'], ou['dn'])
  216.         form_layout.addRow("组织单位*:", self.ou_combo)
  217.         # 记住密码
  218.         self.remember_password_checkbox = QCheckBox("记住密码")
  219.         self.remember_password_checkbox.setChecked(True)
  220.         form_layout.addRow("", self.remember_password_checkbox)
  221.         # 添加表单到主布局
  222.         layout.addLayout(form_layout)
  223.         # 添加按钮
  224.         button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
  225.         button_box.accepted.connect(self.validate_and_accept)
  226.         button_box.rejected.connect(self.reject)
  227.         layout.addWidget(button_box)
  228.     def validate_and_accept(self):
  229.         """验证输入并接受对话框"""
  230.         if not self.display_name_input.text():
  231.             QMessageBox.warning(self, "输入错误", "请输入显示名称")
  232.             return
  233.         if not self.username_input.text():
  234.             QMessageBox.warning(self, "输入错误", "请输入登录账号")
  235.             return
  236.         if not self.password_input.text():
  237.             QMessageBox.warning(self, "输入错误", "请输入密码")
  238.             return
  239.         if self.password_input.text() != self.confirm_password_input.text():
  240.             QMessageBox.warning(self, "输入错误", "两次输入的密码不一致")
  241.             return
  242.         # 验证是否选择了组织单位
  243.         if self.ou_combo.currentIndex() == 0 or self.ou_combo.currentData() is None:
  244.             QMessageBox.warning(self, "输入错误", "请选择组织单位")
  245.             return
  246.         # 验证密码复杂度
  247.         password = self.password_input.text()
  248.         if len(password) < 8:
  249.             QMessageBox.warning(self, "密码错误", "密码长度不能少于8个字符")
  250.             return
  251.         has_upper = any(c.isupper() for c in password)
  252.         has_lower = any(c.islower() for c in password)
  253.         has_digit = any(c.isdigit() for c in password)
  254.         has_special = any(not c.isalnum() for c in password)
  255.         complexity_count = sum([has_upper, has_lower, has_digit, has_special])
  256.         if complexity_count < 3:
  257.             QMessageBox.warning(self, "密码错误", "密码必须包含大写字母、小写字母、数字和特殊字符中的至少三种")
  258.             return
  259.         # 如果勾选了记住密码,确保密码被保存
  260.         # 注意:这里不直接保存密码,而是在对话框接受后由调用者处理
  261.         # 在show_create_user_dialog方法中已添加相应的处理逻辑
  262.         self.accept()
  263. class UnlockAccountDialog(QDialog):
  264.     def __init__(self, locked_users, parent=None):
  265.         super().__init__(parent)
  266.         self.setWindowTitle("解锁账户")
  267.         self.resize(500, 300)
  268.         self.locked_users = locked_users
  269.         # 创建布局
  270.         layout = QVBoxLayout(self)
  271.         # 创建说明标签
  272.         label = QLabel("以下用户账户已被锁定,请选择要解锁的账户:")
  273.         layout.addWidget(label)
  274.         # 创建用户表格
  275.         self.users_table = QTableWidget()
  276.         self.users_table.setColumnCount(2)
  277.         self.users_table.setHorizontalHeaderLabels(["显示名称", "登录账号"])
  278.         self.users_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
  279.         self.users_table.setSelectionBehavior(QTableWidget.SelectRows)
  280.         self.users_table.setSelectionMode(QTableWidget.SingleSelection)
  281.         # 填充表格数据
  282.         self.users_table.setRowCount(len(locked_users))
  283.         for i, user in enumerate(locked_users):
  284.             self.users_table.setItem(i, 0, QTableWidgetItem(user['display_name']))
  285.             self.users_table.setItem(i, 1, QTableWidgetItem(user['username']))
  286.         layout.addWidget(self.users_table)
  287.         # 添加按钮
  288.         button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
  289.         button_box.accepted.connect(self.accept)
  290.         button_box.rejected.connect(self.reject)
  291.         layout.addWidget(button_box)
  292. class CreateOUDialog(QDialog):
  293.     def __init__(self, organizational_units, parent=None):
  294.         super().__init__(parent)
  295.         self.setWindowTitle("创建新组织单位")
  296.         self.resize(400, 200)
  297.         # 创建表单布局
  298.         layout = QVBoxLayout(self)
  299.         form_layout = QFormLayout()
  300.         # 组织单位名称
  301.         self.ou_name_input = QLineEdit()
  302.         form_layout.addRow("组织单位名称:", self.ou_name_input)
  303.         # 父组织单位
  304.         self.parent_ou_combo = QComboBox()
  305.         self.parent_ou_combo.addItem("域根", None)
  306.         for ou in organizational_units:
  307.             self.parent_ou_combo.addItem(ou['name'], ou['dn'])
  308.         form_layout.addRow("父组织单位:", self.parent_ou_combo)
  309.         # 添加表单到主布局
  310.         layout.addLayout(form_layout)
  311.         # 添加按钮
  312.         button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
  313.         button_box.accepted.connect(self.validate_and_accept)
  314.         button_box.rejected.connect(self.reject)
  315.         layout.addWidget(button_box)
  316.     def validate_and_accept(self):
  317.         """验证输入并接受对话框"""
  318.         if not self.ou_name_input.text():
  319.             QMessageBox.warning(self, "输入错误", "请输入组织单位名称")
  320.             return
  321.         self.accept()
  322. class DomainManagerApp(QMainWindow):
  323.     def __init__(self):
  324.         super().__init__()
  325.         self.domain_manager = None
  326.         self.organizational_units = []
  327.         self.users = []
  328.         self.last_selected_ou_index = 0  # 存储上次选择的组织单位索引
  329.         self.init_ui()
  330.     def init_ui(self):
  331.         """初始化用户界面"""
  332.         self.setWindowTitle("域用户管理器3.2 By来乐老弟")
  333.         self.resize(800, 600)
  334.         # 创建中央部件
  335.         central_widget = QWidget()
  336.         self.setCentralWidget(central_widget)
  337.         # 创建主布局
  338.         main_layout = QVBoxLayout(central_widget)
  339.         # 创建连接状态栏
  340.         self.status_label = QLabel("未连接到域控制器")
  341.         self.status_label.setStyleSheet("color: red;")
  342.         # 创建连接按钮
  343.         self.connect_button = QPushButton("连接到域控制器")
  344.         self.connect_button.clicked.connect(self.show_login_dialog)
  345.         # 创建顶部布局
  346.         top_layout = QHBoxLayout()
  347.         top_layout.addWidget(self.status_label)
  348.         top_layout.addStretch(1)
  349.         # 创建赏赞按钮
  350.         self.reward_button = QPushButton("赏赞")
  351.         self.reward_button.clicked.connect(self.show_reward_dialog)
  352.         top_layout.addWidget(self.reward_button)
  353.         top_layout.addWidget(self.connect_button)
  354.         # 创建选项卡部件
  355.         self.tab_widget = QTabWidget()
  356.         # 创建用户管理选项卡
  357.         self.users_tab = QWidget()
  358.         self.init_users_tab()
  359.         self.tab_widget.addTab(self.users_tab, "用户管理")
  360.         # 创建组织单位管理选项卡
  361.         self.ou_tab = QWidget()
  362.         self.init_ou_tab()
  363.         self.tab_widget.addTab(self.ou_tab, "组织单位管理")
  364.         # 添加部件到主布局
  365.         main_layout.addLayout(top_layout)
  366.         main_layout.addWidget(self.tab_widget)
  367.         # 禁用选项卡,直到连接成功
  368.         self.tab_widget.setEnabled(False)
  369.     def init_users_tab(self):
  370.         """初始化用户管理选项卡"""
  371.         layout = QVBoxLayout(self.users_tab)
  372.         # 创建按钮布局
  373.         button_layout = QHBoxLayout()
  374.         # 创建刷新按钮
  375.         refresh_button = QPushButton("刷新用户列表")
  376.         refresh_button.clicked.connect(self.refresh_users)
  377.         button_layout.addWidget(refresh_button)
  378.         # 创建新用户按钮
  379.         create_user_button = QPushButton("创建新用户")
  380.         create_user_button.clicked.connect(self.show_create_user_dialog)
  381.         button_layout.addWidget(create_user_button)
  382.         # 创建删除用户按钮
  383.         delete_user_button = QPushButton("删除选中用户")
  384.         delete_user_button.clicked.connect(self.delete_selected_user)
  385.         button_layout.addWidget(delete_user_button)
  386.         # 创建重置密码按钮
  387.         reset_password_button = QPushButton("重置密码")
  388.         reset_password_button.clicked.connect(self.reset_user_password)
  389.         button_layout.addWidget(reset_password_button)
  390.         # 创建解锁账户按钮
  391.         unlock_account_button = QPushButton("解锁账户")
  392.         unlock_account_button.clicked.connect(self.show_unlock_account_dialog)
  393.         button_layout.addWidget(unlock_account_button)
  394.         # 创建筛选布局
  395.         filter_layout = QHBoxLayout()
  396.         # 创建组织单位筛选下拉框
  397.         filter_layout.addWidget(QLabel("组织单位:"))
  398.         self.ou_filter_combo = QComboBox()
  399.         self.ou_filter_combo.addItem("全部", None)
  400.         self.ou_filter_combo.currentIndexChanged.connect(self.refresh_users)
  401.         filter_layout.addWidget(self.ou_filter_combo)
  402.         # 创建搜索布局
  403.         search_layout = QHBoxLayout()
  404.         # 创建搜索类型下拉框
  405.         self.search_type_combo = QComboBox()
  406.         self.search_type_combo.addItem("所有字段", "any")
  407.         self.search_type_combo.addItem("登录名", "username")
  408.         self.search_type_combo.addItem("显示名称", "display_name")
  409.         self.search_type_combo.addItem("邮箱", "email")
  410.         search_layout.addWidget(self.search_type_combo)
  411.         # 创建搜索输入框
  412.         self.search_input = QLineEdit()
  413.         self.search_input.setPlaceholderText("输入搜索关键词")
  414.         self.search_input.returnPressed.connect(self.search_users)
  415.         search_layout.addWidget(self.search_input)
  416.         # 创建精确匹配复选框
  417.         self.exact_match_checkbox = QCheckBox("精确匹配")
  418.         search_layout.addWidget(self.exact_match_checkbox)
  419.         # 创建搜索按钮
  420.         search_button = QPushButton("搜索")
  421.         search_button.clicked.connect(self.search_users)
  422.         search_layout.addWidget(search_button)
  423.         filter_layout.addLayout(search_layout)
  424.         filter_layout.addStretch(1)
  425.         # 创建用户表格
  426.         self.users_table = QTableWidget()
  427.         self.users_table.setColumnCount(4)
  428.         self.users_table.setHorizontalHeaderLabels(["显示名称", "登录账号", "电子邮件", "组织单位"])
  429.         self.users_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
  430.         self.users_table.setSelectionBehavior(QTableWidget.SelectRows)
  431.         self.users_table.setSelectionMode(QTableWidget.SingleSelection)
  432.         # 添加部件到布局
  433.         layout.addLayout(button_layout)
  434.         layout.addLayout(filter_layout)
  435.         layout.addWidget(self.users_table)
  436.     def init_ou_tab(self):
  437.         """初始化组织单位管理选项卡"""
  438.         layout = QVBoxLayout(self.ou_tab)
  439.         # 创建按钮布局
  440.         button_layout = QHBoxLayout()
  441.         # 创建刷新按钮
  442.         refresh_button = QPushButton("刷新组织单位列表")
  443.         refresh_button.clicked.connect(self.refresh_ous)
  444.         button_layout.addWidget(refresh_button)
  445.         # 创建新组织单位按钮
  446.         create_ou_button = QPushButton("创建新组织单位")
  447.         create_ou_button.clicked.connect(self.show_create_ou_dialog)
  448.         button_layout.addWidget(create_ou_button)
  449.         # 创建组织单位表格
  450.         self.ou_table = QTableWidget()
  451.         self.ou_table.setColumnCount(2)
  452.         self.ou_table.setHorizontalHeaderLabels(["组织单位名称", "DN"])
  453.         self.ou_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
  454.         self.ou_table.setSelectionBehavior(QTableWidget.SelectRows)
  455.         self.ou_table.setSelectionMode(QTableWidget.SingleSelection)
  456.         # 添加部件到布局
  457.         layout.addLayout(button_layout)
  458.         layout.addWidget(self.ou_table)
  459.     def show_login_dialog(self):
  460.         """显示登录对话框"""
  461.         dialog = LoginDialog(self)
  462.         if dialog.exec_():
  463.             # 获取登录信息
  464.             server = dialog.server_input.text()
  465.             domain = dialog.domain_input.text()
  466.             username = dialog.username_input.text()
  467.             password = dialog.password_input.text()
  468.             # 保存登录信息
  469.             dialog.save_login()
  470.             # 创建域管理器并连接
  471.             self.domain_manager = DomainManager(server, domain, username, password)
  472.             if self.domain_manager.connect():
  473.                 self.status_label.setText(f"已连接到域控制器: {server}")
  474.                 self.status_label.setStyleSheet("color: green;")
  475.                 self.connect_button.setText("断开连接")
  476.                 self.connect_button.clicked.disconnect()
  477.                 self.connect_button.clicked.connect(self.disconnect_from_domain)
  478.                 # 启用选项卡
  479.                 self.tab_widget.setEnabled(True)
  480.                 # 刷新数据
  481.                 self.refresh_ous()
  482.                 self.refresh_users()
  483.             else:
  484.                 QMessageBox.critical(self, "连接失败", "无法连接到域控制器,请检查登录信息")
  485.                 self.domain_manager = None
  486.     def disconnect_from_domain(self):
  487.         """断开与域控制器的连接"""
  488.         if self.domain_manager:
  489.             self.domain_manager.disconnect()
  490.             self.domain_manager = None
  491.             self.status_label.setText("未连接到域控制器")
  492.             self.status_label.setStyleSheet("color: red;")
  493.             self.connect_button.setText("连接到域控制器")
  494.             self.connect_button.clicked.disconnect()
  495.             self.connect_button.clicked.connect(self.show_login_dialog)
  496.             # 禁用选项卡
  497.             self.tab_widget.setEnabled(False)
  498.             # 清空数据
  499.             self.users = []
  500.             self.organizational_units = []
  501.             self.users_table.setRowCount(0)
  502.             self.ou_table.setRowCount(0)
  503.             self.ou_filter_combo.clear()
  504.             self.ou_filter_combo.addItem("全部", None)
  505.     def show_reward_dialog(self):
  506.         """显示赏赞对话框"""
  507.         dialog = RewardDialog(self)
  508.         dialog.exec_()
  509.     def refresh_ous(self):
  510.         """刷新组织单位列表"""
  511.         if not self.domain_manager:
  512.             return
  513.         # 获取组织单位列表
  514.         self.organizational_units = self.domain_manager.list_organizational_units()
  515.         # 更新组织单位表格
  516.         self.ou_table.setRowCount(len(self.organizational_units))
  517.         for i, ou in enumerate(self.organizational_units):
  518.             self.ou_table.setItem(i, 0, QTableWidgetItem(ou['name']))
  519.             self.ou_table.setItem(i, 1, QTableWidgetItem(ou['dn']))
  520.         # 更新组织单位筛选下拉框
  521.         current_ou = self.ou_filter_combo.currentData()
  522.         self.ou_filter_combo.clear()
  523.         self.ou_filter_combo.addItem("全部", None)
  524.         for ou in self.organizational_units:
  525.             self.ou_filter_combo.addItem(ou['name'], ou['dn'])
  526.         # 恢复之前选择的组织单位
  527.         if current_ou:
  528.             index = self.ou_filter_combo.findData(current_ou)
  529.             if index >= 0:
  530.                 self.ou_filter_combo.setCurrentIndex(index)
  531.     def search_users(self):
  532.         """搜索用户"""
  533.         if not self.domain_manager:
  534.             return
  535.         keyword = self.search_input.text().strip()
  536.         if not keyword:
  537.             self.refresh_users()
  538.             return
  539.         search_type = self.search_type_combo.currentData()
  540.         exact_match = self.exact_match_checkbox.isChecked()
  541.         # 执行搜索
  542.         users = self.domain_manager.search_users(keyword, search_type, exact_match)
  543.         # 更新表格
  544.         self.users = users
  545.         self.update_users_table()
  546.     def update_users_table(self):
  547.         """更新用户表格显示"""
  548.         self.users_table.setRowCount(len(self.users))
  549.         for i, user in enumerate(self.users):
  550.             self.users_table.setItem(i, 0, QTableWidgetItem(user['display_name']))
  551.             self.users_table.setItem(i, 1, QTableWidgetItem(user['username']))
  552.             self.users_table.setItem(i, 2, QTableWidgetItem(user['email']))
  553.             # 提取组织单位名称
  554.             ou_name = "未知"
  555.             if 'dn' in user:
  556.                 dn_parts = user['dn'].split(',')
  557.                 for part in dn_parts:
  558.                     if part.startswith('OU='):
  559.                         ou_name = part[3:]
  560.                         break
  561.             self.users_table.setItem(i, 3, QTableWidgetItem(ou_name))
  562.     def refresh_users(self):
  563.         """刷新用户列表"""
  564.         if not self.domain_manager:
  565.             return
  566.         # 获取当前选择的组织单位
  567.         ou_dn = self.ou_filter_combo.currentData()
  568.         # 获取用户列表
  569.         self.users = self.domain_manager.list_users(ou_dn)
  570.         # 更新用户表格
  571.         self.users_table.setRowCount(len(self.users))
  572.         for i, user in enumerate(self.users):
  573.             self.users_table.setItem(i, 0, QTableWidgetItem(user['display_name']))
  574.             self.users_table.setItem(i, 1, QTableWidgetItem(user['username']))
  575.             self.users_table.setItem(i, 2, QTableWidgetItem(user['email']))
  576.             # 提取组织单位名称
  577.             ou_name = "未知"
  578.             if 'dn' in user:
  579.                 dn_parts = user['dn'].split(',')
  580.                 for part in dn_parts:
  581.                     if part.startswith('OU='):
  582.                         ou_name = part[3:]
  583.                         break
  584.             self.users_table.setItem(i, 3, QTableWidgetItem(ou_name))
  585.     def show_create_user_dialog(self):
  586.         """显示创建新用户对话框"""
  587.         if not self.domain_manager or not self.organizational_units:
  588.             QMessageBox.warning(self, "无法创建用户", "请先连接到域控制器并确保存在组织单位")
  589.             return
  590.         dialog = CreateUserDialog(self.organizational_units, self)
  591.         # 不设置默认的组织单位,强制用户手动选择
  592.         # 将组织单位下拉框重置为第一项(提示选项)
  593.         dialog.ou_combo.setCurrentIndex(0)
  594.         if dialog.exec_():
  595.             # 保存当前选择的组织单位索引
  596.             self.last_selected_ou_index = dialog.ou_combo.currentIndex()
  597.             # 获取用户信息
  598.             display_name = dialog.display_name_input.text()
  599.             username = dialog.username_input.text()
  600.             password = dialog.password_input.text()
  601.             email = dialog.email_input.text() if dialog.email_input.text() else None
  602.             ou_dn = dialog.ou_combo.currentData()
  603.             # 创建用户
  604.             if self.domain_manager.create_user(username, display_name, password, ou_dn, email):
  605.                 QMessageBox.information(self, "创建成功", f"用户 {display_name} 创建成功")
  606.                 self.refresh_users()
  607.             else:
  608.                 QMessageBox.critical(self, "创建失败", f"无法创建用户 {display_name}")
  609.             # 如果勾选了记住密码,保存用户创建密码配置(与域控制器登录密码分开保存)
  610.             if dialog.remember_password_checkbox.isChecked():
  611.                 # 获取当前域名
  612.                 current_domain = self.domain_manager.domain
  613.                 # 保存特定域的用户密码
  614.                 DomainUserPasswordConfig.save_password_for_domain(current_domain, password, save_password=True)
  615.                 logger.info(f"已保存域 {current_domain} 的用户创建密码配置")
  616.                 # 同时保存到通用配置(向后兼容)
  617.                 user_password_config = UserPasswordConfig(password)
  618.                 UserPasswordConfig.save_config(user_password_config, save_password=True)
  619.                 logger.info(f"已保存通用用户创建密码配置")
  620.             else:
  621.                 # 如果未勾选记住密码,清除之前保存的密码
  622.                 if self.domain_manager and self.domain_manager.domain:
  623.                     # 清除特定域的密码配置
  624.                     DomainUserPasswordConfig.save_password_for_domain(self.domain_manager.domain, None, save_password=False)
  625.                     logger.info(f"已清除域 {self.domain_manager.domain} 的用户创建密码配置")
  626.                 # 同时清除通用配置
  627.                 UserPasswordConfig.save_config(UserPasswordConfig(), save_password=False)
  628.                 logger.info("已清除通用用户创建密码配置")
  629.     def delete_selected_user(self):
  630.         """删除选中的用户"""
  631.         if not self.domain_manager:
  632.             return
  633.         # 获取选中的行
  634.         selected_rows = self.users_table.selectedIndexes()
  635.         if not selected_rows:
  636.             QMessageBox.warning(self, "未选择用户", "请先选择要删除的用户")
  637.             return
  638.         row = selected_rows[0].row()
  639.         user = self.users[row]
  640.         # 确认删除
  641.         reply = QMessageBox.question(self, "确认删除", f"确定要删除用户 {user['display_name']} 吗?",
  642.                                     QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
  643.         if reply == QMessageBox.Yes:
  644.             # 删除用户
  645.             if self.domain_manager.delete_user(user['dn']):
  646.                 QMessageBox.information(self, "删除成功", f"用户 {user['display_name']} 删除成功")
  647.                 self.refresh_users()
  648.             else:
  649.                 QMessageBox.critical(self, "删除失败", f"无法删除用户 {user['display_name']}")
  650.     def reset_user_password(self):
  651.         """重置用户密码"""
  652.         if not self.domain_manager:
  653.             return
  654.         # 获取选中的行
  655.         selected_rows = self.users_table.selectedIndexes()
  656.         if not selected_rows:
  657.             QMessageBox.warning(self, "未选择用户", "请先选择要重置密码的用户")
  658.             return
  659.         row = selected_rows[0].row()
  660.         user = self.users[row]
  661.         # 获取新密码
  662.         new_password, ok = QInputDialog.getText(self, "重置密码", f"请输入 {user['display_name']} 的新密码:\n(密码必须至少8个字符,且包含大写字母、小写字母、数字和特殊字符中的至少三种)",
  663.                                               QLineEdit.Password)
  664.         if ok and new_password:
  665.             # 重置密码
  666.             result = self.domain_manager.reset_password(user['dn'], new_password)
  667.             if isinstance(result, tuple) and len(result) == 2:
  668.                 # 新版本的reset_password返回(成功标志, 错误信息)
  669.                 success, error_msg = result
  670.                 if success:
  671.                     QMessageBox.information(self, "重置成功", f"用户 {user['display_name']} 的密码重置成功")
  672.                 else:
  673.                     QMessageBox.critical(self, "密码不符合要求", f"无法重置密码: {error_msg}")
  674.             else:
  675.                 # 兼容旧版本的reset_password只返回成功标志
  676.                 if result:
  677.                     QMessageBox.information(self, "重置成功", f"用户 {user['display_name']} 的密码重置成功")
  678.                 else:
  679.                     QMessageBox.critical(self, "重置失败", f"无法重置用户 {user['display_name']} 的密码")
  680.     def show_unlock_account_dialog(self):
  681.         """显示解锁账户对话框"""
  682.         if not self.domain_manager:
  683.             return
  684.         # 获取锁定的用户账户
  685.         locked_users = self.domain_manager.get_locked_users()
  686.         if not locked_users:
  687.             QMessageBox.information(self, "无锁定账户", "当前没有被锁定的用户账户")
  688.             return
  689.         # 显示解锁账户对话框
  690.         dialog = UnlockAccountDialog(locked_users, self)
  691.         if dialog.exec_():
  692.             # 获取选中的行
  693.             selected_rows = dialog.users_table.selectedIndexes()
  694.             if not selected_rows:
  695.                 QMessageBox.warning(self, "未选择用户", "请先选择要解锁的用户账户")
  696.                 return
  697.             row = selected_rows[0].row()
  698.             user = dialog.locked_users[row]
  699.             # 解锁用户账户
  700.             if self.domain_manager.unlock_user(user['dn']):
  701.                 QMessageBox.information(self, "解锁成功", f"用户 {user['display_name']} 的账户已成功解锁")
  702.             else:
  703.                 QMessageBox.critical(self, "解锁失败", f"无法解锁用户 {user['display_name']} 的账户")
  704.     def show_create_ou_dialog(self):
  705.         """显示创建新组织单位对话框"""
  706.         if not self.domain_manager:
  707.             QMessageBox.warning(self, "无法创建组织单位", "请先连接到域控制器")
  708.             return
  709.         dialog = CreateOUDialog(self.organizational_units, self)
  710.         if dialog.exec_():
  711.             # 获取组织单位信息
  712.             ou_name = dialog.ou_name_input.text()
  713.             parent_ou = dialog.parent_ou_combo.currentData()
  714.             # 创建组织单位
  715.             if self.domain_manager.create_organizational_unit(ou_name, parent_ou):
  716.                 QMessageBox.information(self, "创建成功", f"组织单位 {ou_name} 创建成功")
  717.                 self.refresh_ous()
  718.             else:
  719.                 QMessageBox.critical(self, "创建失败", f"无法创建组织单位 {ou_name}")
  720. def main():
  721.     app = QApplication(sys.argv)
  722.     window = DomainManagerApp()
  723.     window.show()
  724.     sys.exit(app.exec_())
  725. if __name__ == "__main__":
  726.     main()
复制代码


















本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

发表于 2025-10-24 14:50:29 | 显示全部楼层
感谢楼主分享,收下了<span style="float:left;margin-right:5px">


<font color="ffffffff">                                        藏起来的小尾巴,不让你看!
回复

使用道具 举报

发表于 2025-10-24 14:50:58 | 显示全部楼层
楼主,这个工具可以编辑修改用户信息不?和本地服务器上域用户和计算里面的用户属性的那些功能有啥区别?比如能够设置用户登录时间,登录到等等,有这些功能吗?
回复

使用道具 举报

发表于 2025-10-24 14:51:23 | 显示全部楼层
域管理确实是很实用的工具 谢谢楼主分享
回复

使用道具 举报

发表于 2025-10-24 14:51:30 | 显示全部楼层
这简直就是企业维护搬砖人的神器哇
回复

使用道具 举报

发表于 2025-10-24 14:52:14 | 显示全部楼层
谢谢分享, 我试试
回复

使用道具 举报

发表于 2025-10-24 14:53:09 | 显示全部楼层
真是个好软件,域控制软件,谢谢分享
回复

使用道具 举报

发表于 2025-10-24 14:53:53 | 显示全部楼层
这工具确实能方便很多

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

发表于 2025-10-24 14:54:47 | 显示全部楼层
感谢分享,吾爱大神真多
回复

使用道具 举报

发表于 2025-10-24 14:55:08 | 显示全部楼层
谢谢大佬,下来试试
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表