吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1780|回复: 42
上一主题 下一主题
收起左侧

[原创工具] IT偷懒小工具-域控用户管理

  [复制链接]
跳转到指定楼层
楼主
dl_hou 发表于 2025-3-21 09:36 回帖奖励
在你的工作场景中如何,经常对域用户进行管理,该工具是你的选择之一,可以添加登录到N个域,对N个域进行域用户管理,密码登可以设置保存方便下次使用。
注:该软件可能不符合你单位的安全管理要求,如不符合请勿使用。另外选择保存密码的话是以明文保存的。

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


[Asm] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
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()


















免费评分

参与人数 2吾爱币 +8 热心值 +2 收起 理由
aminqiu1015 + 1 + 1 谢谢@Thanks!
风之暇想 + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
jun269 发表于 2025-3-22 21:37
楼主,这个工具可以编辑修改用户信息不?和本地服务器上域用户和计算里面的用户属性的那些功能有啥区别?比如能够设置用户登录时间,登录到等等,有这些功能吗?
推荐
jun269 发表于 2025-3-22 22:15
dl_hou 发表于 2025-3-22 22:10
这个是作为域管理员管理域账户的工具,不是管理本地计算器账户的工具。域用户也就是开个登录账号,删除账 ...

我说的不是本地计算账户那个意思,我的意思是域控服务器上的 域用户和计算机 里面用户属性里面有很多选择项的,比如:限制用户登陆时间,等等
沙发
dickwolf 发表于 2025-3-21 22:00
3#
wuaiwuxiwuxuexi 发表于 2025-3-21 22:24
这简直就是企业维护搬砖人的神器哇
4#
elicdr 发表于 2025-3-21 22:25
感谢分享,吾爱真的什么都有
5#
cwldy 发表于 2025-3-21 22:35
谢谢分享, 我试试
6#
hzzl85 发表于 2025-3-21 22:48
真是个好软件,域控制软件,谢谢分享
7#
jun269 发表于 2025-3-22 09:43
这工具确实能方便很多
8#
w84295 发表于 2025-3-22 09:53
感谢分享,吾爱大神真多
9#
llttyy00 发表于 2025-3-22 20:19
谢谢大佬,下来试试
10#
lty9009 发表于 2025-3-22 20:42
很方便的小工具
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-3-28 05:03

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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