328 lines
11 KiB
JavaScript
328 lines
11 KiB
JavaScript
/**
|
|
* 统计卡片权限测试脚本
|
|
* 功能:验证统计卡片区域的权限控制是否正确
|
|
* 时间:2025-06-30 18:55:00
|
|
*/
|
|
|
|
const axios = require('axios');
|
|
const colors = require('colors');
|
|
|
|
// 测试配置
|
|
const config = {
|
|
baseURL: 'http://localhost/dev-api',
|
|
timeout: 10000,
|
|
testAccounts: [
|
|
{ username: 'admin', password: 'admin123', role: 'superadmin', expectVisible: true },
|
|
{
|
|
username: 'property_admin_test',
|
|
password: 'admin123',
|
|
role: 'property_maintenance_admin',
|
|
expectVisible: true,
|
|
},
|
|
{
|
|
username: 'maintenance_test',
|
|
password: 'admin123',
|
|
role: 'maintenance_worker',
|
|
expectVisible: false,
|
|
},
|
|
],
|
|
};
|
|
|
|
/**
|
|
* AES+RSA双重加密登录
|
|
*/
|
|
async function encryptedLogin(username, password) {
|
|
const CryptoJS = require('crypto-js');
|
|
const NodeRSA = require('node-rsa');
|
|
|
|
// 配置信息
|
|
const rsaKey =
|
|
'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==';
|
|
const clientId = 'e5cd7e4891bf95d1d19206ce24a7b32e';
|
|
|
|
// 生成32位随机AES密钥
|
|
function generateAESKey() {
|
|
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
let result = '';
|
|
for (let i = 0; i < 32; i++) {
|
|
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// AES加密
|
|
function aesEncrypt(data, key) {
|
|
const keyUtf8 = CryptoJS.enc.Utf8.parse(key);
|
|
return CryptoJS.AES.encrypt(data, keyUtf8, {
|
|
mode: CryptoJS.mode.ECB,
|
|
padding: CryptoJS.pad.Pkcs7,
|
|
}).toString();
|
|
}
|
|
|
|
// RSA加密AES密钥
|
|
function rsaEncrypt(aesKey) {
|
|
const pemKey = `-----BEGIN PUBLIC KEY-----\n${rsaKey}\n-----END PUBLIC KEY-----`;
|
|
const rsaKey_obj = new NodeRSA(pemKey);
|
|
rsaKey_obj.setOptions({ encryptionScheme: 'pkcs1' });
|
|
const aesKeyBase64 = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(aesKey));
|
|
return rsaKey_obj.encrypt(aesKeyBase64, 'base64');
|
|
}
|
|
|
|
// 生成AES密钥并加密登录数据
|
|
const aesKey = generateAESKey();
|
|
const loginData = {
|
|
tenantId: '000000',
|
|
username: username,
|
|
password: password,
|
|
clientId: clientId,
|
|
grantType: 'password',
|
|
};
|
|
|
|
const encryptedData = aesEncrypt(JSON.stringify(loginData), aesKey);
|
|
const encryptedKey = rsaEncrypt(aesKey);
|
|
|
|
// 设置请求头
|
|
const headers = {
|
|
'Content-Type': 'application/json;charset=utf-8',
|
|
clientid: clientId,
|
|
'encrypt-key': encryptedKey,
|
|
referer: 'http://localhost/login?redirect=%252Findex',
|
|
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
|
|
isToken: 'false',
|
|
isEncrypt: 'true',
|
|
repeatSubmit: 'false',
|
|
};
|
|
|
|
try {
|
|
const response = await axios.post(`${config.baseURL}/auth/login`, encryptedData, {
|
|
headers: headers,
|
|
timeout: config.timeout,
|
|
});
|
|
|
|
if (response.data.code === 200 && response.data.data?.access_token) {
|
|
return response.data.data.access_token;
|
|
} else {
|
|
throw new Error(response.data.msg || 'Login failed');
|
|
}
|
|
} catch (error) {
|
|
throw new Error(`登录失败: ${error.message}`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取用户信息
|
|
*/
|
|
async function getUserInfo(token) {
|
|
try {
|
|
const response = await axios.get(`${config.baseURL}/system/user/getInfo`, {
|
|
headers: {
|
|
Authorization: `Bearer ${token}`,
|
|
clientid: 'e5cd7e4891bf95d1d19206ce24a7b32e',
|
|
'Content-Type': 'application/json;charset=utf-8',
|
|
},
|
|
timeout: config.timeout,
|
|
});
|
|
|
|
if (response.data.code === 200) {
|
|
return response.data.data;
|
|
} else {
|
|
throw new Error(response.data.msg || 'Get user info failed');
|
|
}
|
|
} catch (error) {
|
|
throw new Error(`获取用户信息失败: ${error.message}`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取统计数据(验证接口权限)
|
|
*/
|
|
async function getStatistics(token) {
|
|
try {
|
|
const response = await axios.get(`${config.baseURL}/pm/repairOrder/statistics`, {
|
|
headers: {
|
|
Authorization: `Bearer ${token}`,
|
|
clientid: 'e5cd7e4891bf95d1d19206ce24a7b32e',
|
|
'Content-Type': 'application/json;charset=utf-8',
|
|
},
|
|
timeout: config.timeout,
|
|
});
|
|
|
|
return {
|
|
success: response.data.code === 200,
|
|
data: response.data.data,
|
|
message: response.data.msg,
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
data: null,
|
|
message: error.response?.data?.msg || error.message,
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 检查用户角色权限
|
|
*/
|
|
function checkStatisticsPermission(userInfo) {
|
|
if (!userInfo || !userInfo.roles) {
|
|
return false;
|
|
}
|
|
|
|
// 检查是否为超级管理员
|
|
if (userInfo.admin) {
|
|
return true;
|
|
}
|
|
|
|
// 检查是否为物业维修管理员
|
|
const roles = userInfo.roles || [];
|
|
return roles.some((role) => role.roleKey === 'property_maintenance_admin');
|
|
}
|
|
|
|
/**
|
|
* 执行权限测试
|
|
*/
|
|
async function testStatisticsPermissions() {
|
|
console.log(colors.cyan('='.repeat(80)));
|
|
console.log(colors.cyan('统计卡片权限测试开始'));
|
|
console.log(colors.cyan('='.repeat(80)));
|
|
|
|
const results = [];
|
|
|
|
for (const account of config.testAccounts) {
|
|
console.log(colors.yellow(`\n正在测试账号: ${account.username} (${account.role})`));
|
|
|
|
try {
|
|
// 登录获取Token
|
|
console.log(' ├─ 正在登录...');
|
|
const token = await encryptedLogin(account.username, account.password);
|
|
console.log(' ├─ 登录成功 ✓');
|
|
|
|
// 获取用户信息
|
|
console.log(' ├─ 获取用户信息...');
|
|
const userInfo = await getUserInfo(token);
|
|
console.log(' ├─ 用户信息获取成功 ✓');
|
|
|
|
// 检查前端权限逻辑
|
|
const frontendPermission = checkStatisticsPermission(userInfo);
|
|
console.log(
|
|
` ├─ 前端权限检查: ${frontendPermission ? '有权限' : '无权限'} ${
|
|
frontendPermission === account.expectVisible ? '✓' : '✗'
|
|
}`,
|
|
);
|
|
|
|
// 测试后端统计接口
|
|
console.log(' ├─ 测试统计接口...');
|
|
const statsResult = await getStatistics(token);
|
|
console.log(
|
|
` ├─ 统计接口调用: ${statsResult.success ? '成功' : '失败'} ${
|
|
statsResult.success === account.expectVisible ? '✓' : '✗'
|
|
}`,
|
|
);
|
|
|
|
const testResult = {
|
|
username: account.username,
|
|
role: account.role,
|
|
expectedVisible: account.expectVisible,
|
|
frontendPermission: frontendPermission,
|
|
backendPermission: statsResult.success,
|
|
frontendCorrect: frontendPermission === account.expectVisible,
|
|
backendCorrect: statsResult.success === account.expectVisible,
|
|
message: statsResult.message,
|
|
};
|
|
|
|
results.push(testResult);
|
|
|
|
if (testResult.frontendCorrect && testResult.backendCorrect) {
|
|
console.log(' └─ 测试结果: ' + colors.green('通过 ✓'));
|
|
} else {
|
|
console.log(' └─ 测试结果: ' + colors.red('失败 ✗'));
|
|
}
|
|
} catch (error) {
|
|
console.log(' └─ 测试结果: ' + colors.red(`错误 - ${error.message}`));
|
|
results.push({
|
|
username: account.username,
|
|
role: account.role,
|
|
expectedVisible: account.expectVisible,
|
|
frontendPermission: false,
|
|
backendPermission: false,
|
|
frontendCorrect: false,
|
|
backendCorrect: false,
|
|
message: error.message,
|
|
});
|
|
}
|
|
}
|
|
|
|
// 输出测试结果汇总
|
|
console.log(colors.cyan('\n='.repeat(80)));
|
|
console.log(colors.cyan('测试结果汇总'));
|
|
console.log(colors.cyan('='.repeat(80)));
|
|
|
|
console.log('\n账号权限测试结果:');
|
|
console.log(
|
|
'┌─────────────────────┬──────────────────────┬──────────────┬──────────────┬──────┐',
|
|
);
|
|
console.log(
|
|
'│ 账号 │ 角色 │ 前端权限 │ 后端权限 │ 状态 │',
|
|
);
|
|
console.log(
|
|
'├─────────────────────┼──────────────────────┼──────────────┼──────────────┼──────┤',
|
|
);
|
|
|
|
let allTestsPassed = true;
|
|
for (const result of results) {
|
|
const username = result.username.padEnd(17);
|
|
const role = result.role.padEnd(18);
|
|
const frontend = (result.frontendPermission ? '有权限' : '无权限').padEnd(10);
|
|
const backend = (result.backendPermission ? '有权限' : '无权限').padEnd(10);
|
|
const status = result.frontendCorrect && result.backendCorrect ? '✓ 通过' : '✗ 失败';
|
|
const statusColor =
|
|
result.frontendCorrect && result.backendCorrect ? colors.green : colors.red;
|
|
|
|
console.log(
|
|
`│ ${username} │ ${role} │ ${frontend} │ ${backend} │ ${statusColor(status)} │`,
|
|
);
|
|
|
|
if (!result.frontendCorrect || !result.backendCorrect) {
|
|
allTestsPassed = false;
|
|
}
|
|
}
|
|
|
|
console.log(
|
|
'└─────────────────────┴──────────────────────┴──────────────┴──────────────┴──────┘',
|
|
);
|
|
|
|
// 测试总结
|
|
console.log(colors.cyan('\n测试总结:'));
|
|
if (allTestsPassed) {
|
|
console.log(colors.green('✓ 所有权限测试均通过!统计卡片权限控制正确实现。'));
|
|
console.log(colors.green(' - 超级管理员和物业维修管理员可以访问统计功能'));
|
|
console.log(colors.green(' - 维修人员和其他角色无法访问统计功能'));
|
|
} else {
|
|
console.log(colors.red('✗ 部分权限测试失败,请检查权限配置!'));
|
|
|
|
// 输出失败的测试详情
|
|
const failedTests = results.filter((r) => !r.frontendCorrect || !r.backendCorrect);
|
|
for (const failed of failedTests) {
|
|
console.log(colors.red(` - ${failed.username}: ${failed.message}`));
|
|
}
|
|
}
|
|
|
|
console.log(colors.cyan('\n='.repeat(80)));
|
|
}
|
|
|
|
/**
|
|
* 主函数
|
|
*/
|
|
async function main() {
|
|
try {
|
|
await testStatisticsPermissions();
|
|
} catch (error) {
|
|
console.error(colors.red('测试执行失败:'), error.message);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
// 运行测试
|
|
main().catch(console.error);
|