完善 MCS 桌面代理与开炼机动作同步,修复原料相关菜单权限,桌面端新增上辅机 MES 菜单。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace YY.Admin.Services.Service.EquipmentDb;
|
||||
|
||||
/// <summary>
|
||||
/// 设备库 SQL 白名单:仅允许访问 MCS 中间表白名单表。
|
||||
/// </summary>
|
||||
public static class EquipmentDbWhitelist
|
||||
{
|
||||
private static readonly HashSet<string> AllowedTables = new(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
"MCSToMES_Alarm", "MCSToMES_MixAlarm", "MCSToMES_MixAct", "MCSToMES_Act_Mill", "MCSToMES_MixBatch",
|
||||
"MCSToMES_MixCon", "MCSToMES_MixCurve", "MCSToMES_MixStep", "MCSToMES_MixWeight",
|
||||
"MCSToMES_MixExePlan", "MCSToMES_BinToMater", "MCSToMES_AutoXLLog", "MCSToMES_CheckScaleLog",
|
||||
"MESToMCS_Material", "MESToMCS_MixPlan", "MESToMCS_Recipe",
|
||||
"MESToMCS_Recipe_MixStep", "MESToMCS_Recipe_Weight"
|
||||
};
|
||||
|
||||
private static readonly Regex Dangerous = new(
|
||||
@"\b(DROP|ALTER|TRUNCATE|EXEC|EXECUTE|xp_|sp_|INTO\s+OUTFILE|OPENROWSET|OPENDATASOURCE)\b",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex TableRef = new(
|
||||
@"\b(?:FROM|INTO|UPDATE|JOIN)\s+\[?(?<t>[A-Za-z0-9_]+)\]?",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
public static bool IsAllowedTable(string? table)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(table))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return AllowedTables.Contains(table.Trim());
|
||||
}
|
||||
|
||||
public static void ValidateSql(string? sql, string? tableHint = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(sql))
|
||||
{
|
||||
throw new InvalidOperationException("SQL 不能为空");
|
||||
}
|
||||
if (Dangerous.IsMatch(sql))
|
||||
{
|
||||
throw new InvalidOperationException("SQL 包含禁止关键字");
|
||||
}
|
||||
var trimmed = sql.TrimStart();
|
||||
var isSelect = trimmed.StartsWith("SELECT", StringComparison.OrdinalIgnoreCase);
|
||||
var isInsert = trimmed.StartsWith("INSERT", StringComparison.OrdinalIgnoreCase);
|
||||
var isUpdate = trimmed.StartsWith("UPDATE", StringComparison.OrdinalIgnoreCase);
|
||||
var isDelete = trimmed.StartsWith("DELETE", StringComparison.OrdinalIgnoreCase);
|
||||
if (!(isSelect || isInsert || isUpdate || isDelete))
|
||||
{
|
||||
throw new InvalidOperationException("仅允许 SELECT/INSERT/UPDATE/DELETE");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(tableHint) && !IsAllowedTable(tableHint))
|
||||
{
|
||||
throw new InvalidOperationException($"表不在白名单: {tableHint}");
|
||||
}
|
||||
|
||||
foreach (Match m in TableRef.Matches(sql))
|
||||
{
|
||||
var t = m.Groups["t"].Value;
|
||||
if (string.Equals(t, "TOP", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(t, "SELECT", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(t, "SET", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(t, "VALUES", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(t, "WHERE", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!IsAllowedTable(t))
|
||||
{
|
||||
throw new InvalidOperationException($"SQL 引用了未授权表: {t}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user