import
sys
import
os
import
json
import
logging
from PyQt5.QtWidgets
import
(QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
QPushButton, QLabel, QLineEdit, QComboBox, QTableWidget,
QTableWidgetItem, QMessageBox, QTabWidget, QFormLayout,
QGroupBox, QDialog, QDialogButtonBox, QCheckBox, QHeaderView,
QSplitter, QFrame, QFileDialog, QInputDialog)
from PyQt5.QtCore
import
Qt, QSize
from PyQt5.QtGui
import
QIcon, QFont, QPixmap
# 添加资源路径处理函数
def resource_path(relative_path):
""
"获取资源的绝对路径,兼容开发环境和PyInstaller打包后的环境"
""
try:
# PyInstaller创建临时文件夹,将路径存储在_MEIPASS中
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(
"."
)
return os.path.join(base_path, relative_path)
class RewardDialog(QDialog):
def __init__(self, parent=
None
):
super().__init__(parent)
self.setWindowTitle(
"赏赞"
)
self.resize(400, 450)
# 创建布局
layout = QVBoxLayout(self)
# 加载赏赞图片,使用resource_path函数获取正确路径
reward_pixmap = QPixmap(resource_path(
"reward.jpg"
))
if
not
reward_pixmap.isNull():
# 调整图片大小
reward_pixmap = reward_pixmap.scaled(300, 300, Qt.KeepAspectRatio)
# 创建标签显示图片
image_label = QLabel()
image_label.setPixmap(reward_pixmap)
image_label.setAlignment(Qt.AlignCenter)
layout.addWidget(image_label)
else
:
# 图片加载失败时显示错误信息
error_label = QLabel(
"无法加载赏赞图片"
)
error_label.setAlignment(Qt.AlignCenter)
layout.addWidget(error_label)
# 添加文字说明
text_label = QLabel(
"您的慷慨是对作者最大的支持"
)
text_label.setAlignment(Qt.AlignCenter)
font = QFont()
font.setPointSize(12)
text_label.setFont(font)
layout.addWidget(text_label)
# 添加关闭按钮
button_box = QDialogButtonBox(QDialogButtonBox.Close)
button_box.rejected.connect(self.reject)
layout.addWidget(button_box)
from domain_manager
import
DomainManager, DomainConfig, UserPasswordConfig, DomainUserPasswordConfig
# 配置日志
logging.basicConfig(level=logging.INFO, format=
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(
'domain_gui'
)
class LoginDialog(QDialog):
def __init__(self, parent=
None
):
super().__init__(parent)
self.setWindowTitle(
"域控制器登录"
)
self.resize(400, 250)
# 创建表单布局
layout = QVBoxLayout(self)
form_layout = QFormLayout()
# 域选择下拉框
self.domain_combo = QComboBox()
self.domain_combo.currentIndexChanged.connect(self.on_domain_selected)
form_layout.addRow(
"选择域:"
, self.domain_combo)
# 服务器地址
self.server_input = QLineEdit()
form_layout.addRow(
"服务器地址:"
, self.server_input)
# 域名
self.domain_input = QLineEdit()
form_layout.addRow(
"域名:"
, self.domain_input)
# 用户名
self.username_input = QLineEdit()
form_layout.addRow(
"用户名:"
, self.username_input)
# 密码
self.password_input = QLineEdit()
self.password_input.setEchoMode(QLineEdit.Password)
form_layout.addRow(
"密码:"
, self.password_input)
# 记住登录信息
self.remember_checkbox = QCheckBox(
"记住登录信息"
)
# 记住密码
self.remember_password_checkbox = QCheckBox(
"记住密码"
)
# 创建水平布局来放置复选框
checkbox_layout = QHBoxLayout()
checkbox_layout.addWidget(self.remember_checkbox)
checkbox_layout.addWidget(self.remember_password_checkbox)
# 添加表单到主布局
layout.addLayout(form_layout)
layout.addLayout(checkbox_layout)
# 添加按钮
button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
button_box.accepted.connect(self.accept)
button_box.rejected.connect(self.reject)
layout.addWidget(button_box)
# 加载保存的登录信息
self.load_saved_login()
def load_saved_login(self):
""
"加载保存的登录信息"
""
try:
configs = DomainConfig.load_configs()
self.domain_combo.clear()
self.domain_combo.addItem(
"新建域配置..."
)
for
i, config
in
enumerate(configs):
display_text = f
"{config.domain} ({config.server_address})"
self.domain_combo.addItem(display_text, config)
if
configs:
self.domain_combo.setCurrentIndex(1) # 选择第一个域配置
self.remember_checkbox.setChecked(True)
if
configs[0].password:
self.remember_password_checkbox.setChecked(True)
except Exception as e:
logger.
error
(f
"加载登录信息失败: {e}"
)
def on_domain_selected(self, index):
""
"当选择域时更新表单"
""
if
index == 0: # 新建域配置
self.server_input.clear()
self.domain_input.clear()
self.username_input.clear()
self.password_input.clear()
self.remember_checkbox.setChecked(False)
self.remember_password_checkbox.setChecked(False)
elif index > 0:
config = self.domain_combo.currentData()
if
config:
self.server_input.setText(config.server_address)
self.domain_input.setText(config.domain)
self.username_input.setText(config.username)
if
config.password:
self.password_input.setText(config.password)
self.remember_password_checkbox.setChecked(True)
def save_login(self):
""
"保存登录信息"
""
if
self.remember_checkbox.isChecked():
configs = DomainConfig.load_configs()
# 创建新的域配置
new_config = DomainConfig(
self.server_input
.text
(),
self.domain_input
.text
(),
self.username_input
.text
(),
self.password_input
.text
()
if
self.remember_password_checkbox.isChecked()
else
None
)
# 检查是否已存在相同的域配置
exists = False
for
i, config
in
enumerate(configs):
if
config.domain == new_config.domain
and
config.server_address == new_config.server_address:
configs[i] = new_config
exists = True
break
if
not
exists:
configs.append(new_config)
# 保存配置
DomainConfig.save_configs(configs, save_passwords=self.remember_password_checkbox.isChecked())
logger.info(
"域控制器登录信息保存成功"
)
elif os.path.exists(
'login_config.json'
):
os.remove(
'login_config.json'
)
logger.info(
"域控制器登录信息已删除"
)
class CreateUserDialog(QDialog):
def __init__(self, organizational_units, parent=
None
):
super().__init__(parent)
self.setWindowTitle(
"创建新用户"
)
self.resize(400, 300)
# 创建表单布局
layout = QVBoxLayout(self)
form_layout = QFormLayout()
# 尝试加载上次保存的密码
self.saved_password =
None
try:
# 获取当前连接的域名
parent_window = self.parent()
current_domain =
None
if
parent_window
and
hasattr(parent_window,
'domain_manager'
)
and
parent_window.domain_manager:
current_domain = parent_window.domain_manager.domain
if
current_domain:
# 使用DomainUserPasswordConfig加载特定域的用户密码配置
self.saved_password = DomainUserPasswordConfig.get_password_for_domain(current_domain)
# 如果没有特定域的密码配置,尝试使用通用配置(向后兼容)
if
not
self.saved_password:
user_password_config = UserPasswordConfig.load_config()
if
user_password_config.password:
self.saved_password = user_password_config.password
except Exception as e:
logger.
error
(f
"加载保存的密码失败: {e}"
)
# 显示名称
self.display_name_input = QLineEdit()
form_layout.addRow(
"显示名称:"
, self.display_name_input)
# 登录账号
self.username_input = QLineEdit()
form_layout.addRow(
"登录账号:"
, self.username_input)
# 密码
self.password_input = QLineEdit()
self.password_input.setEchoMode(QLineEdit.Password)
# 如果有保存的密码,自动填充
if
self.saved_password:
self.password_input.setText(self.saved_password)
form_layout.addRow(
"密码:"
, self.password_input)
# 确认密码
self.confirm_password_input = QLineEdit()
self.confirm_password_input.setEchoMode(QLineEdit.Password)
# 如果有保存的密码,自动填充确认密码
if
self.saved_password:
self.confirm_password_input.setText(self.saved_password)
form_layout.addRow(
"确认密码:"
, self.confirm_password_input)
# 电子邮件
self.email_input = QLineEdit()
form_layout.addRow(
"电子邮件:"
, self.email_input)
# 组织单位
self.ou_combo = QComboBox()
# 添加提示选项,但不设置实际数据
self.ou_combo.addItem(
"请选择组织单位"
,
None
)
for
ou
in
organizational_units:
self.ou_combo.addItem(ou[
'name'
], ou[
'dn'
])
form_layout.addRow(
"组织单位*:"
, self.ou_combo)
# 记住密码
self.remember_password_checkbox = QCheckBox(
"记住密码"
)
self.remember_password_checkbox.setChecked(True)
form_layout.addRow(
""
, self.remember_password_checkbox)
# 添加表单到主布局
layout.addLayout(form_layout)
# 添加按钮
button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
button_box.accepted.connect(self.validate_and_accept)
button_box.rejected.connect(self.reject)
layout.addWidget(button_box)
def validate_and_accept(self):
""
"验证输入并接受对话框"
""
if
not
self.display_name_input
.text
():
QMessageBox.warning(self,
"输入错误"
,
"请输入显示名称"
)
return
if
not
self.username_input
.text
():
QMessageBox.warning(self,
"输入错误"
,
"请输入登录账号"
)
return
if
not
self.password_input
.text
():
QMessageBox.warning(self,
"输入错误"
,
"请输入密码"
)
return
if
self.password_input
.text
() != self.confirm_password_input
.text
():
QMessageBox.warning(self,
"输入错误"
,
"两次输入的密码不一致"
)
return
# 验证是否选择了组织单位
if
self.ou_combo.currentIndex() == 0
or
self.ou_combo.currentData() is
None
:
QMessageBox.warning(self,
"输入错误"
,
"请选择组织单位"
)
return
# 验证密码复杂度
password = self.password_input
.text
()
if
len(password) < 8:
QMessageBox.warning(self,
"密码错误"
,
"密码长度不能少于8个字符"
)
return
has_upper = any(
c
.isupper()
for
c
in
password)
has_lower = any(
c
.islower()
for
c
in
password)
has_digit = any(
c
.isdigit()
for
c
in
password)
has_special = any(
not
c
.isalnum()
for
c
in
password)
complexity_count = sum([has_upper, has_lower, has_digit, has_special])
if
complexity_count < 3:
QMessageBox.warning(self,
"密码错误"
,
"密码必须包含大写字母、小写字母、数字和特殊字符中的至少三种"
)
return
# 如果勾选了记住密码,确保密码被保存
# 注意:这里不直接保存密码,而是在对话框接受后由调用者处理
# 在show_create_user_dialog方法中已添加相应的处理逻辑
self.accept()
class UnlockAccountDialog(QDialog):
def __init__(self, locked_users, parent=
None
):
super().__init__(parent)
self.setWindowTitle(
"解锁账户"
)
self.resize(500, 300)
self.locked_users = locked_users
# 创建布局
layout = QVBoxLayout(self)
# 创建说明标签
label
= QLabel(
"以下用户账户已被锁定,请选择要解锁的账户:"
)
layout.addWidget(
label
)
# 创建用户表格
self.users_table = QTableWidget()
self.users_table.setColumnCount(2)
self.users_table.setHorizontalHeaderLabels([
"显示名称"
,
"登录账号"
])
self.users_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
self.users_table.setSelectionBehavior(QTableWidget.SelectRows)
self.users_table.setSelectionMode(QTableWidget.SingleSelection)
# 填充表格数据
self.users_table.setRowCount(len(locked_users))
for
i, user
in
enumerate(locked_users):
self.users_table.setItem(i, 0, QTableWidgetItem(user[
'display_name'
]))
self.users_table.setItem(i, 1, QTableWidgetItem(user[
'username'
]))
layout.addWidget(self.users_table)
# 添加按钮
button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
button_box.accepted.connect(self.accept)
button_box.rejected.connect(self.reject)
layout.addWidget(button_box)
class CreateOUDialog(QDialog):
def __init__(self, organizational_units, parent=
None
):
super().__init__(parent)
self.setWindowTitle(
"创建新组织单位"
)
self.resize(400, 200)
# 创建表单布局
layout = QVBoxLayout(self)
form_layout = QFormLayout()
# 组织单位名称
self.ou_name_input = QLineEdit()
form_layout.addRow(
"组织单位名称:"
, self.ou_name_input)
# 父组织单位
self.parent_ou_combo = QComboBox()
self.parent_ou_combo.addItem(
"域根"
,
None
)
for
ou
in
organizational_units:
self.parent_ou_combo.addItem(ou[
'name'
], ou[
'dn'
])
form_layout.addRow(
"父组织单位:"
, self.parent_ou_combo)
# 添加表单到主布局
layout.addLayout(form_layout)
# 添加按钮
button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
button_box.accepted.connect(self.validate_and_accept)
button_box.rejected.connect(self.reject)
layout.addWidget(button_box)
def validate_and_accept(self):
""
"验证输入并接受对话框"
""
if
not
self.ou_name_input
.text
():
QMessageBox.warning(self,
"输入错误"
,
"请输入组织单位名称"
)
return
self.accept()
class DomainManagerApp(QMainWindow):
def __init__(self):
super().__init__()
self.domain_manager =
None
self.organizational_units = []
self.users = []
self.last_selected_ou_index = 0 # 存储上次选择的组织单位索引
self.init_ui()
def init_ui(self):
""
"初始化用户界面"
""
self.setWindowTitle(
"域用户管理器3.2 By来乐老弟"
)
self.resize(800, 600)
# 创建中央部件
central_widget = QWidget()
self.setCentralWidget(central_widget)
# 创建主布局
main_layout = QVBoxLayout(central_widget)
# 创建连接状态栏
self.status_label = QLabel(
"未连接到域控制器"
)
self.status_label.setStyleSheet(
"color: red;"
)
# 创建连接按钮
self.connect_button = QPushButton(
"连接到域控制器"
)
self.connect_button.clicked.connect(self.show_login_dialog)
# 创建顶部布局
top_layout = QHBoxLayout()
top_layout.addWidget(self.status_label)
top_layout.addStretch(1)
# 创建赏赞按钮
self.reward_button = QPushButton(
"赏赞"
)
self.reward_button.clicked.connect(self.show_reward_dialog)
top_layout.addWidget(self.reward_button)
top_layout.addWidget(self.connect_button)
# 创建选项卡部件
self.tab_widget = QTabWidget()
# 创建用户管理选项卡
self.users_tab = QWidget()
self.init_users_tab()
self.tab_widget.addTab(self.users_tab,
"用户管理"
)
# 创建组织单位管理选项卡
self.ou_tab = QWidget()
self.init_ou_tab()
self.tab_widget.addTab(self.ou_tab,
"组织单位管理"
)
# 添加部件到主布局
main_layout.addLayout(top_layout)
main_layout.addWidget(self.tab_widget)
# 禁用选项卡,直到连接成功
self.tab_widget.setEnabled(False)
def init_users_tab(self):
""
"初始化用户管理选项卡"
""
layout = QVBoxLayout(self.users_tab)
# 创建按钮布局
button_layout = QHBoxLayout()
# 创建刷新按钮
refresh_button = QPushButton(
"刷新用户列表"
)
refresh_button.clicked.connect(self.refresh_users)
button_layout.addWidget(refresh_button)
# 创建新用户按钮
create_user_button = QPushButton(
"创建新用户"
)
create_user_button.clicked.connect(self.show_create_user_dialog)
button_layout.addWidget(create_user_button)
# 创建删除用户按钮
delete_user_button = QPushButton(
"删除选中用户"
)
delete_user_button.clicked.connect(self.delete_selected_user)
button_layout.addWidget(delete_user_button)
# 创建重置密码按钮
reset_password_button = QPushButton(
"重置密码"
)
reset_password_button.clicked.connect(self.reset_user_password)
button_layout.addWidget(reset_password_button)
# 创建解锁账户按钮
unlock_account_button = QPushButton(
"解锁账户"
)
unlock_account_button.clicked.connect(self.show_unlock_account_dialog)
button_layout.addWidget(unlock_account_button)
# 创建筛选布局
filter_layout = QHBoxLayout()
# 创建组织单位筛选下拉框
filter_layout.addWidget(QLabel(
"组织单位:"
))
self.ou_filter_combo = QComboBox()
self.ou_filter_combo.addItem(
"全部"
,
None
)
self.ou_filter_combo.currentIndexChanged.connect(self.refresh_users)
filter_layout.addWidget(self.ou_filter_combo)
# 创建搜索布局
search_layout = QHBoxLayout()
# 创建搜索类型下拉框
self.search_type_combo = QComboBox()
self.search_type_combo.addItem(
"所有字段"
,
"any"
)
self.search_type_combo.addItem(
"登录名"
,
"username"
)
self.search_type_combo.addItem(
"显示名称"
,
"display_name"
)
self.search_type_combo.addItem(
"邮箱"
,
"email"
)
search_layout.addWidget(self.search_type_combo)
# 创建搜索输入框
self.search_input = QLineEdit()
self.search_input.setPlaceholderText(
"输入搜索关键词"
)
self.search_input.returnPressed.connect(self.search_users)
search_layout.addWidget(self.search_input)
# 创建精确匹配复选框
self.exact_match_checkbox = QCheckBox(
"精确匹配"
)
search_layout.addWidget(self.exact_match_checkbox)
# 创建搜索按钮
search_button = QPushButton(
"搜索"
)
search_button.clicked.connect(self.search_users)
search_layout.addWidget(search_button)
filter_layout.addLayout(search_layout)
filter_layout.addStretch(1)
# 创建用户表格
self.users_table = QTableWidget()
self.users_table.setColumnCount(4)
self.users_table.setHorizontalHeaderLabels([
"显示名称"
,
"登录账号"
,
"电子邮件"
,
"组织单位"
])
self.users_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
self.users_table.setSelectionBehavior(QTableWidget.SelectRows)
self.users_table.setSelectionMode(QTableWidget.SingleSelection)
# 添加部件到布局
layout.addLayout(button_layout)
layout.addLayout(filter_layout)
layout.addWidget(self.users_table)
def init_ou_tab(self):
""
"初始化组织单位管理选项卡"
""
layout = QVBoxLayout(self.ou_tab)
# 创建按钮布局
button_layout = QHBoxLayout()
# 创建刷新按钮
refresh_button = QPushButton(
"刷新组织单位列表"
)
refresh_button.clicked.connect(self.refresh_ous)
button_layout.addWidget(refresh_button)
# 创建新组织单位按钮
create_ou_button = QPushButton(
"创建新组织单位"
)
create_ou_button.clicked.connect(self.show_create_ou_dialog)
button_layout.addWidget(create_ou_button)
# 创建组织单位表格
self.ou_table = QTableWidget()
self.ou_table.setColumnCount(2)
self.ou_table.setHorizontalHeaderLabels([
"组织单位名称"
,
"DN"
])
self.ou_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
self.ou_table.setSelectionBehavior(QTableWidget.SelectRows)
self.ou_table.setSelectionMode(QTableWidget.SingleSelection)
# 添加部件到布局
layout.addLayout(button_layout)
layout.addWidget(self.ou_table)
def show_login_dialog(self):
""
"显示登录对话框"
""
dialog = LoginDialog(self)
if
dialog.exec_():
# 获取登录信息
server = dialog.server_input
.text
()
domain = dialog.domain_input
.text
()
username = dialog.username_input
.text
()
password = dialog.password_input
.text
()
# 保存登录信息
dialog.save_login()
# 创建域管理器并连接
self.domain_manager = DomainManager(server, domain, username, password)
if
self.domain_manager.connect():
self.status_label.setText(f
"已连接到域控制器: {server}"
)
self.status_label.setStyleSheet(
"color: green;"
)
self.connect_button.setText(
"断开连接"
)
self.connect_button.clicked.disconnect()
self.connect_button.clicked.connect(self.disconnect_from_domain)
# 启用选项卡
self.tab_widget.setEnabled(True)
# 刷新数据
self.refresh_ous()
self.refresh_users()
else
:
QMessageBox.critical(self,
"连接失败"
,
"无法连接到域控制器,请检查登录信息"
)
self.domain_manager =
None
def disconnect_from_domain(self):
""
"断开与域控制器的连接"
""
if
self.domain_manager:
self.domain_manager.disconnect()
self.domain_manager =
None
self.status_label.setText(
"未连接到域控制器"
)
self.status_label.setStyleSheet(
"color: red;"
)
self.connect_button.setText(
"连接到域控制器"
)
self.connect_button.clicked.disconnect()
self.connect_button.clicked.connect(self.show_login_dialog)
# 禁用选项卡
self.tab_widget.setEnabled(False)
# 清空数据
self.users = []
self.organizational_units = []
self.users_table.setRowCount(0)
self.ou_table.setRowCount(0)
self.ou_filter_combo.clear()
self.ou_filter_combo.addItem(
"全部"
,
None
)
def show_reward_dialog(self):
""
"显示赏赞对话框"
""
dialog = RewardDialog(self)
dialog.exec_()
def refresh_ous(self):
""
"刷新组织单位列表"
""
if
not
self.domain_manager:
return
# 获取组织单位列表
self.organizational_units = self.domain_manager.list_organizational_units()
# 更新组织单位表格
self.ou_table.setRowCount(len(self.organizational_units))
for
i, ou
in
enumerate(self.organizational_units):
self.ou_table.setItem(i, 0, QTableWidgetItem(ou[
'name'
]))
self.ou_table.setItem(i, 1, QTableWidgetItem(ou[
'dn'
]))
# 更新组织单位筛选下拉框
current_ou = self.ou_filter_combo.currentData()
self.ou_filter_combo.clear()
self.ou_filter_combo.addItem(
"全部"
,
None
)
for
ou
in
self.organizational_units:
self.ou_filter_combo.addItem(ou[
'name'
], ou[
'dn'
])
# 恢复之前选择的组织单位
if
current_ou:
index = self.ou_filter_combo.findData(current_ou)
if
index >= 0:
self.ou_filter_combo.setCurrentIndex(index)
def search_users(self):
""
"搜索用户"
""
if
not
self.domain_manager:
return
keyword = self.search_input
.text
().strip()
if
not
keyword:
self.refresh_users()
return
search_type = self.search_type_combo.currentData()
exact_match = self.exact_match_checkbox.isChecked()
# 执行搜索
users = self.domain_manager.search_users(keyword, search_type, exact_match)
# 更新表格
self.users = users
self.update_users_table()
def update_users_table(self):
""
"更新用户表格显示"
""
self.users_table.setRowCount(len(self.users))
for
i, user
in
enumerate(self.users):
self.users_table.setItem(i, 0, QTableWidgetItem(user[
'display_name'
]))
self.users_table.setItem(i, 1, QTableWidgetItem(user[
'username'
]))
self.users_table.setItem(i, 2, QTableWidgetItem(user[
'email'
]))
# 提取组织单位名称
ou_name =
"未知"
if
'dn'
in
user:
dn_parts = user[
'dn'
].split(
','
)
for
part
in
dn_parts:
if
part.startswith(
'OU='
):
ou_name = part[3:]
break
self.users_table.setItem(i, 3, QTableWidgetItem(ou_name))
def refresh_users(self):
""
"刷新用户列表"
""
if
not
self.domain_manager:
return
# 获取当前选择的组织单位
ou_dn = self.ou_filter_combo.currentData()
# 获取用户列表
self.users = self.domain_manager.list_users(ou_dn)
# 更新用户表格
self.users_table.setRowCount(len(self.users))
for
i, user
in
enumerate(self.users):
self.users_table.setItem(i, 0, QTableWidgetItem(user[
'display_name'
]))
self.users_table.setItem(i, 1, QTableWidgetItem(user[
'username'
]))
self.users_table.setItem(i, 2, QTableWidgetItem(user[
'email'
]))
# 提取组织单位名称
ou_name =
"未知"
if
'dn'
in
user:
dn_parts = user[
'dn'
].split(
','
)
for
part
in
dn_parts:
if
part.startswith(
'OU='
):
ou_name = part[3:]
break
self.users_table.setItem(i, 3, QTableWidgetItem(ou_name))
def show_create_user_dialog(self):
""
"显示创建新用户对话框"
""
if
not
self.domain_manager
or
not
self.organizational_units:
QMessageBox.warning(self,
"无法创建用户"
,
"请先连接到域控制器并确保存在组织单位"
)
return
dialog = CreateUserDialog(self.organizational_units, self)
# 不设置默认的组织单位,强制用户手动选择
# 将组织单位下拉框重置为第一项(提示选项)
dialog.ou_combo.setCurrentIndex(0)
if
dialog.exec_():
# 保存当前选择的组织单位索引
self.last_selected_ou_index = dialog.ou_combo.currentIndex()
# 获取用户信息
display_name = dialog.display_name_input
.text
()
username = dialog.username_input
.text
()
password = dialog.password_input
.text
()
email = dialog.email_input
.text
()
if
dialog.email_input
.text
()
else
None
ou_dn = dialog.ou_combo.currentData()
# 创建用户
if
self.domain_manager.create_user(username, display_name, password, ou_dn, email):
QMessageBox.information(self,
"创建成功"
, f
"用户 {display_name} 创建成功"
)
self.refresh_users()
else
:
QMessageBox.critical(self,
"创建失败"
, f
"无法创建用户 {display_name}"
)
# 如果勾选了记住密码,保存用户创建密码配置(与域控制器登录密码分开保存)
if
dialog.remember_password_checkbox.isChecked():
# 获取当前域名
current_domain = self.domain_manager.domain
# 保存特定域的用户密码
DomainUserPasswordConfig.save_password_for_domain(current_domain, password, save_password=True)
logger.info(f
"已保存域 {current_domain} 的用户创建密码配置"
)
# 同时保存到通用配置(向后兼容)
user_password_config = UserPasswordConfig(password)
UserPasswordConfig.save_config(user_password_config, save_password=True)
logger.info(f
"已保存通用用户创建密码配置"
)
else
:
# 如果未勾选记住密码,清除之前保存的密码
if
self.domain_manager
and
self.domain_manager.domain:
# 清除特定域的密码配置
DomainUserPasswordConfig.save_password_for_domain(self.domain_manager.domain,
None
, save_password=False)
logger.info(f
"已清除域 {self.domain_manager.domain} 的用户创建密码配置"
)
# 同时清除通用配置
UserPasswordConfig.save_config(UserPasswordConfig(), save_password=False)
logger.info(
"已清除通用用户创建密码配置"
)
def delete_selected_user(self):
""
"删除选中的用户"
""
if
not
self.domain_manager:
return
# 获取选中的行
selected_rows = self.users_table.selectedIndexes()
if
not
selected_rows:
QMessageBox.warning(self,
"未选择用户"
,
"请先选择要删除的用户"
)
return
row = selected_rows[0].row()
user = self.users[row]
# 确认删除
reply = QMessageBox.question(self,
"确认删除"
, f
"确定要删除用户 {user['display_name']} 吗?"
,
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if
reply == QMessageBox.Yes:
# 删除用户
if
self.domain_manager.delete_user(user[
'dn'
]):
QMessageBox.information(self,
"删除成功"
, f
"用户 {user['display_name']} 删除成功"
)
self.refresh_users()
else
:
QMessageBox.critical(self,
"删除失败"
, f
"无法删除用户 {user['display_name']}"
)
def reset_user_password(self):
""
"重置用户密码"
""
if
not
self.domain_manager:
return
# 获取选中的行
selected_rows = self.users_table.selectedIndexes()
if
not
selected_rows:
QMessageBox.warning(self,
"未选择用户"
,
"请先选择要重置密码的用户"
)
return
row = selected_rows[0].row()
user = self.users[row]
# 获取新密码
new_password, ok = QInputDialog.getText(self,
"重置密码"
, f
"请输入 {user['display_name']} 的新密码:\n(密码必须至少8个字符,且包含大写字母、小写字母、数字和特殊字符中的至少三种)"
,
QLineEdit.Password)
if
ok
and
new_password:
# 重置密码
result = self.domain_manager.reset_password(user[
'dn'
], new_password)
if
isinstance(result, tuple)
and
len(result) == 2:
# 新版本的reset_password返回(成功标志, 错误信息)
success, error_msg = result
if
success:
QMessageBox.information(self,
"重置成功"
, f
"用户 {user['display_name']} 的密码重置成功"
)
else
:
QMessageBox.critical(self,
"密码不符合要求"
, f
"无法重置密码: {error_msg}"
)
else
:
# 兼容旧版本的reset_password只返回成功标志
if
result:
QMessageBox.information(self,
"重置成功"
, f
"用户 {user['display_name']} 的密码重置成功"
)
else
:
QMessageBox.critical(self,
"重置失败"
, f
"无法重置用户 {user['display_name']} 的密码"
)
def show_unlock_account_dialog(self):
""
"显示解锁账户对话框"
""
if
not
self.domain_manager:
return
# 获取锁定的用户账户
locked_users = self.domain_manager.get_locked_users()
if
not
locked_users:
QMessageBox.information(self,
"无锁定账户"
,
"当前没有被锁定的用户账户"
)
return
# 显示解锁账户对话框
dialog = UnlockAccountDialog(locked_users, self)
if
dialog.exec_():
# 获取选中的行
selected_rows = dialog.users_table.selectedIndexes()
if
not
selected_rows:
QMessageBox.warning(self,
"未选择用户"
,
"请先选择要解锁的用户账户"
)
return
row = selected_rows[0].row()
user = dialog.locked_users[row]
# 解锁用户账户
if
self.domain_manager.unlock_user(user[
'dn'
]):
QMessageBox.information(self,
"解锁成功"
, f
"用户 {user['display_name']} 的账户已成功解锁"
)
else
:
QMessageBox.critical(self,
"解锁失败"
, f
"无法解锁用户 {user['display_name']} 的账户"
)
def show_create_ou_dialog(self):
""
"显示创建新组织单位对话框"
""
if
not
self.domain_manager:
QMessageBox.warning(self,
"无法创建组织单位"
,
"请先连接到域控制器"
)
return
dialog = CreateOUDialog(self.organizational_units, self)
if
dialog.exec_():
# 获取组织单位信息
ou_name = dialog.ou_name_input
.text
()
parent_ou = dialog.parent_ou_combo.currentData()
# 创建组织单位
if
self.domain_manager.create_organizational_unit(ou_name, parent_ou):
QMessageBox.information(self,
"创建成功"
, f
"组织单位 {ou_name} 创建成功"
)
self.refresh_ous()
else
:
QMessageBox.critical(self,
"创建失败"
, f
"无法创建组织单位 {ou_name}"
)
def main():
app = QApplication(sys.argv)
window = DomainManagerApp()
window.show()
sys
.exit
(app.exec_())
if
__name__ ==
"__main__"
:
main()