多组用户权限批量管理系统优化指南
概述
本指南旨在帮助开发者优化现有的共享文件夹权限管理系统,使其能够支持一次性向多个组添加多个用户。通过修改后端逻辑和前端界面,用户可以更高效地管理权限,特别适用于需要批量处理的场景。本指南涵盖了后端Flask应用程序的增强、前端HTML页面的调整以及JSON配置文件的优化。
后端优化
更新权限添加逻辑
为了支持一次性向多个组添加多个用户,需要修改后端的`add_permission` API,使其能够处理多组权限的请求。以下是优化后的Flask后端代码:
from flask_cors import CORS
from flask import Flask, jsonify, request
import json
import subprocess
app = Flask(__name__)
CORS(app)
# 加载共享文件夹配置
def load_config():
with open('permissions_config.json', 'r', encoding='utf-8') as f:
return json.load(f)
@app.route('/get-folders', methods=['GET'])
def get_folders():
try:
config = load_config()
folders = list(config.keys())
return jsonify(folders), 200
except Exception as e:
return jsonify({"error": "无法加载共享文件夹路径"}), 500
def get_samaccountname(description):
"""通过 Description 查找 SamAccountName"""
try:
query_command = f"Get-ADUser -Filter {{Description -eq '{description}'}} | Select-Object -ExpandProperty SamAccountName"
query_result = subprocess.run(
["powershell", "-Command", query_command],
capture_output=True,
text=True
)
if query_result.returncode == 0 and query_result.stdout.strip():
return query_result.stdout.strip()
else:
return None # 未找到用户
except Exception as e:
print(f"查询用户失败: {e}")
return None
@app.route('/add-permission', methods=['POST'])
def add_permission():
try:
data = request.json
folders = data.get('folders', []) # 支持多个文件夹
descriptions = data.get('usernames', []) # 用户输入的 Description 列表
permission = data.get('permission')
if not folders or not descriptions or not permission:
return jsonify({"error": "缺少必要参数"}), 400
config = load_config()
results = []
for folder in folders:
if folder not in config:
results.append(f"无效的共享文件夹路径: {folder}")
continue
if permission not in config[folder]:
results.append(f"无效的权限类型: {permission} 在 {folder} 中")
continue
group_name = config[folder][permission]
for description in descriptions:
samaccountname = get_samaccountname(description)
if not samaccountname:
results.append(f"用户 {description} 不存在。")
continue
# 检查用户是否已在组中
check_command = f"Get-ADGroupMember -Identity {group_name} | Where-Object {{ $_.SamAccountName -eq '{samaccountname}' }}"
check_result = subprocess.run(
["powershell", "-Command", check_command],
capture_output=True,
text=True
)
if check_result.returncode == 0 and samaccountname in check_result.stdout:
results.append(f"用户 {description} 已经在组 {group_name} 中,无需重复添加。")
continue
# 添加用户到组
add_command = f"Add-ADGroupMember -Identity {group_name} -Members {samaccountname}"
print(f"执行命令: {add_command}")
add_result = subprocess.run(
["powershell", "-Command", add_command],
capture_output=True,
text=True
)
if add_result.returncode == 0:
message = f"成功为用户 {description} 添加 {folder} 的 {permission} 权限!"
print(message)
results.append(message)
else:
error_message = add_result.stderr.strip()
if "ObjectNotFound" in error_message:
results.append(f"用户 {description} 不存在。")
else:
results.append(f"用户 {description} 添加失败: {error_message}")
return jsonify({"message": " | ".join(results)}), 200
except Exception as e:
print(f"添加权限失败: {e}")
return jsonify({"error": "内部服务器错误"}), 500
if __name__ == '__main__':
app.run(debug=True)
代码说明
- 加载配置文件函数: 创建了一个单独的函数`load_config`来加载`permissions_config.json`,以避免代码重复。
- 支持多组选择: 在`add_permission`函数中,将`folder`参数替换为`folders`,以支持多个文件夹的选择。
- 循环处理每个文件夹和用户: 通过嵌套循环,分别处理每个选定的文件夹和每个用户,确保每个用户都被添加到所有选定的组中。
- 错误处理: 增强了错误处理逻辑,确保每个步骤的失败都能被捕捉并反馈给用户。
前端优化
调整HTML表单结构
为了支持多组选择,需要修改前端的HTML表单,使其能够选择多个文件夹。以下是更新后的前端代码:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>共享文件夹权限管理</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
<style>
body {
background-color: #f8f9fa;
padding: 20px;
}
h1 {
margin-bottom: 20px;
}
.form-container {
max-width: 700px;
margin: auto;
background: white;
padding: 30px;
border-radius: 10px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
.btn-submit {
background-color: #28a745;
color: white;
}
.btn-submit:hover {
background-color: #218838;
}
</style>
</head>
<body>
<div class="form-container">
<h1 class="text-center" style="color:#cc9900;">共享文件夹权限管理</h1>
<form id="permissionForm" onsubmit="event.preventDefault(); submitForm();">
<div class="mb-3">
<label for="folders" class="form-label">选择共享文件夹 (可多选):</label>
<select id="folders" name="folders" class="form-select" multiple required>
<option value="" disabled>请选择共享文件夹</option>
</select>
<div class="form-text">按住 Ctrl 键 (Windows) 或 Command 键 (Mac) 进行多选。</div>
</div>
<div class="mb-3">
<label for="username" class="form-label">输入用户名(多个用逗号分隔):</label>
<input type="text" id="username" name="username" class="form-control" placeholder="例如:zuokunlin, anda, zhuoke" required>
</div>
<div class="mb-3">
<label class="form-label">选择权限类型:</label>
<div class="form-check">
<input type="radio" id="readOnly" name="permission" value="ReadOnly" class="form-check-input" required>
<label for="readOnly" class="form-check-label">只读</label>
</div>
<div class="form-check">
<input type="radio" id="readWrite" name="permission" value="ReadWrite" class="form-check-input" required>
<label for="readWrite" class="form-check-label">读写</label>
</div>
</div>
<button type="submit" class="btn btn-submit w-100">提交</button>
</form>
</div>
<script>
// 页面加载时请求共享文件夹路径
window.onload = function() {
fetch('http://127.0.0.1:5000/get-folders')
.then(response => response.json())
.then(folders => {
const folderSelect = document.getElementById('folders');
folders.forEach(folder => {
const option = document.createElement('option');
option.value = folder;
option.textContent = folder;
folderSelect.appendChild(option);
});
})
.catch(error => console.error('加载共享路径失败:', error));
};
// 提交表单
function submitForm() {
const folderSelect = document.getElementById('folders');
const selectedOptions = Array.from(folderSelect.selectedOptions).map(option => option.value);
const usernames = document.getElementById('username').value.split(',').map(user => user.trim());
const permission = document.querySelector('input[name="permission"]:checked').value;
fetch('http://127.0.0.1:5000/add-permission', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ folders: selectedOptions, usernames: usernames, permission: permission })
})
.then(response => {
if (!response.ok) {
return response.json().then(data => {
throw new Error(data.error || '未知错误');
});
}
return response.json();
})
.then(data => {
alert(data.message);
})
.catch(error => {
alert(`操作失败: ${error.message}`);
console.error('请求失败:', error);
});
}
</script>
</body>
</html>
代码说明
- 多选下拉列表: 将``元素的`multiple`属性设置为支持多选,并添加提示文本说明如何进行多选操作。
- JavaScript逻辑更新: 在`submitForm`函数中,使用`selectedOptions`数组获取所有被选中的文件夹,并在请求体中发送`folders`数组。
- 用户输入处理: 保持对用户名输入的处理方式不变,支持逗号分隔的多个用户名。
- 权限类型选择: 保持单选按钮的设计,用户选择一种权限类型即可。
JSON配置文件优化
确保`permissions_config.json`包含所有需要管理的共享文件夹及其对应的权限组。以下是一个示例配置:
{
"\\\\pubnas\\Private": {
"ReadOnly": "dorisart-read",
"ReadWrite": "dorisart-wr"
},
"\\\\box\\ArtAsset": {
"ReadOnly": "ArtAsset-R",
"ReadWrite": "ArtAsset"
},
"\\\\box\\ArtCenterToolset": {
"ReadOnly": "ArtCenterToolset_R",
"ReadWrite": "ArtCenterToolset_RW"
},
"\\\\box\\Project\\UE4": {
"ReadOnly": "",
"ReadWrite": "proj_UE4"
},
"\\\\box\\Department\\PublishingCenter\\VideoLibrary": {
"ReadOnly": "BOX_Pub_VideoLibrary-R",
"ReadWrite": "BOX_Pub_VideoLibrary"
},
"\\\\box\\Department\\PublishingCenter\\10-发行中心资料": {
"ReadOnly": "Publishing-R",
"ReadWrite": "pub_10_rw"
}
}
代码说明
-
结构: JSON文件中每个键代表一个共享文件夹路径,值为一个对象,包含不同权限类型对应的组名称。
-
灵活性: 通过调整JSON文件,可以轻松添加或删除共享文件夹及其权限组,增强了系统的可维护性。
完整系统运行流程
- 前端选择多组文件夹和输入多个用户名: 用户在前端界面中选择一个或多个共享文件夹,并输入多个用户名(以逗号分隔)。
- 提交请求到后端: 用户点击“提交”按钮后,前端将所选文件夹、用户名和权限类型发送到后端API。
- 后端处理请求: 后端接收请求,遍历每个文件夹和用户名,执行添加用户到指定组的操作,同时处理可能出现的错误。
- 返回结果反馈: 后端将处理结果返回给前端,前端通过弹窗向用户展示操作结果。
最佳实践与建议
- 输入验证: 在前端和后端都应加强对用户输入的验证,确保数据的有效性和安全性,防止潜在的注入攻击。
- 错误处理: 提供详细的错误信息有助于快速定位问题,但同时要注意不要泄露敏感信息。可以在生产环境中限制错误信息的详细程度。
- 用户体验: 在处理大批量请求时,可以考虑添加进度条或加载指示器,提升用户体验。
- 日志记录: 后端应记录关键操作和错误信息,便于日后审计和问题排查。
- 权限管理: 确保只有授权用户可以访问和操作该权限管理系统,保护共享文件夹的安全。
结论
通过上述后端和前端的优化,权限管理系统现已具备批量向多个组添加多个用户的能力,极大提升了管理效率。作为新手,建议仔细阅读并理解每一部分代码的功能和逻辑,并在测试环境中进行充分测试,确保系统的稳定性和安全性。在未来,可以进一步扩展功能,如添加权限删除、权限修改等,以满足更复杂的需求。
Last updated January 7, 2025