Sic.Framework-Nanjing-Baishi/MECF.Framework.Common/MECF/Framework/Common/Account/Extends/RoleLoader.cs

478 lines
14 KiB
C#
Raw Normal View History

2023-04-13 11:51:03 +08:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Aitex.Common.Util;
using Aitex.Core.RT.Log;
2023-04-13 11:51:03 +08:00
namespace MECF.Framework.Common.Account.Extends
{
/// <summary>
2023-09-05 09:27:56 +08:00
/// 角色加载器从_Account.xml文件加载角色。
/// </summary>
2023-04-13 11:51:03 +08:00
public class RoleLoader : XmlLoader
{
#region Variables
private const string NODE_NAME_PERMS_GROUP = "Perms";
private const string NODE_NAME_PERMS_ITEM = "Perm";
private readonly MenuLoader _menuLoader;
private List<Role> _roleList;
private List<AccountEx> _accountList;
2023-04-13 11:51:03 +08:00
#endregion
#region Constructors
2023-09-05 09:27:56 +08:00
/// <summary>
/// 创建角色加载器对象实例。
/// </summary>
/// <param name="fileName">角色配置文件名称通常为_Account.xml</param>
public RoleLoader(string fileName)
: base(fileName)
2023-04-13 11:51:03 +08:00
{
_menuLoader = new MenuLoader(PathManager.GetCfgDir() + "menu.xml");
_menuLoader.Load();
2023-04-13 11:51:03 +08:00
}
#endregion
#region Properties
/// <summary>
/// 返回角色列表。
/// </summary>
public List<Role> RoleList
2023-04-13 11:51:03 +08:00
{
get => _roleList;
set => _roleList = value;
2023-04-13 11:51:03 +08:00
}
/// <summary>
/// 返回账号列表。
/// </summary>
public List<AccountEx> AccountList
2023-04-13 11:51:03 +08:00
{
get => _accountList;
set => _accountList = value;
2023-04-13 11:51:03 +08:00
}
#endregion
#region Methods
2023-04-13 11:51:03 +08:00
/*/// <inheritdoc />
public override void Load()
{
// 先检查旧的_Account.xml文件是否存在如果存在则加载旧的配置保存时使用_AccountEx.xml文件。
if (File.Exists(_OldAccountXmlFile))
{
XmlDoc = XDocument.Load(_OldAccountXmlFile);
AnalyzeXml();
return;
}
else if (File.Exists((FileName)))
{
XmlDoc = XDocument.Load(FileName);
AnalyzeXml();
return;
}
throw new FileNotFoundException("File " + FileName + " not be found");
}
*/
/// <summary>
/// 获取配置文件中定义的所有菜单项。
/// </summary>
/// <returns></returns>
public List<AppMenu> GetAllMenus()
{
return _menuLoader.MenuList;
}
/// <summary>
/// 获取所有非超级用户角色列表。
/// </summary>
/// <returns></returns>
2023-04-13 11:51:03 +08:00
public List<Role> GetRoles()
{
return _roleList.Where((Role e) => !e.IsSuper).ToList();
2023-04-13 11:51:03 +08:00
}
/// <summary>
/// 获取所有非超级用户账号列表。
/// </summary>
/// <returns></returns>
2023-04-13 11:51:03 +08:00
public List<AccountEx> GetAccounts()
{
return _accountList.Where((AccountEx e) => !e.IsSuper).ToList();
2023-04-13 11:51:03 +08:00
}
/// <summary>
/// 解析Account.xml文件。
/// </summary>
2023-04-13 11:51:03 +08:00
protected override void AnalyzeXml()
{
if (XmlDoc == null)
2023-04-13 11:51:03 +08:00
{
return;
}
var roleItems = from r in XmlDoc.Descendants("roleItem")
2023-04-13 11:51:03 +08:00
select (r);
var list = new List<Role>();
foreach (var roleNode in roleItems)
2023-04-13 11:51:03 +08:00
{
var strRoleId = roleNode.Attribute("id").Value;
var strRoleName = roleNode.Attribute("name").Value;
var strIsAutoLogout = roleNode.Attribute("autologout").Value;
var strAutoLogoutTime = roleNode.Attribute("logouttime").Value;
int.TryParse(strAutoLogoutTime, out var logoutTime);
var isAutoLogout = ((strIsAutoLogout == "1"));
var strBuildIn = roleNode.Attribute("buildin")?.Value ?? "false";
if (!bool.TryParse(strBuildIn, out var isBuildIn))
isBuildIn = false;
// ID为0 ~ 3的角色强制为系统内置角色禁止删除
if (strRoleId is "0" or "1" or "2" or "3")
isBuildIn = true;
var strDescription = roleNode.Attribute("description")?.Value ?? "";
// 旧版的权限保存方式为字符串形式,新版更改为<Perm />节点列表。
// 为兼容旧格式此处应该判断roleNode节点中的内容将旧版自动转换为PermissionControlItem列表
if (roleNode.FirstNode is XText)
{
// 旧版
var permContent = roleNode.Value;
var helper = new PermissionHelper();
helper.ParsePermission(permContent);
var role = new Role(strRoleId, strRoleName, isAutoLogout, logoutTime,
helper.MenuPermissionDictionary, isBuildIn, strDescription);
list.Add(role);
}
else
{
// 新版
var permList = new Dictionary<string, MenuPermissionEnum>();
foreach (var grpPerms in roleNode.Elements(NODE_NAME_PERMS_GROUP))
{
foreach (var xe in grpPerms.Elements(NODE_NAME_PERMS_ITEM))
{
var permName = xe.Attribute("name")?.Value;
var strPermValue = xe.Attribute("value")?.Value ?? "1";
if (!int.TryParse(strPermValue, out var permValue))
permValue = (int)MenuPermissionEnum.MP_NONE;
if (!string.IsNullOrEmpty(permName))
permList[permName] = (MenuPermissionEnum)permValue;
}
}
var role = new Role(strRoleId, strRoleName, isAutoLogout, logoutTime,
permList, isBuildIn, strDescription);
list.Add(role);
}
2023-04-13 11:51:03 +08:00
}
var roleAdmin = new Role("-1", "Administrators", true, 20, null, true, null)
2023-04-13 11:51:03 +08:00
{
IsSuper = true
};
list.Add(roleAdmin);
_roleList = list;
var users = from r in XmlDoc.Descendants("userItem")
2023-04-13 11:51:03 +08:00
select (r);
var lstUsers = new List<AccountEx>();
foreach (var userNode in users)
2023-04-13 11:51:03 +08:00
{
var lstRolesBelongTo = new List<string>();
var strUserId = userNode.Attribute("id").Value;
var strLoginName = userNode.Attribute("loginname").Value;
var strPassword = Decrypt(userNode.Attribute("password").Value);
var strFirstName = userNode.Attribute("firstname").Value;
var strLastName = userNode.Attribute("lastname").Value;
var strEmail = userNode.Attribute("email").Value;
var strDescription = "";
if (userNode.Attribute("description") != null)
2023-04-13 11:51:03 +08:00
{
strDescription = userNode.Attribute("description").Value;
2023-04-13 11:51:03 +08:00
}
var userRoles = from ro in userNode.Descendants("role")
2023-04-13 11:51:03 +08:00
select (ro);
foreach (var userRoleNode in userRoles)
2023-04-13 11:51:03 +08:00
{
var strRoleId = userRoleNode.Attribute("id").Value;
lstRolesBelongTo.Add(strRoleId);
2023-04-13 11:51:03 +08:00
}
var item3 = new AccountEx(strUserId, strLoginName, strPassword, strFirstName, strLastName, strEmail, lstRolesBelongTo, strDescription);
lstUsers.Add(item3);
2023-04-13 11:51:03 +08:00
}
var admin = new AccountEx("-1", "sic_admin", "sic_admin", "", "", "", new List<string> { "-1" })
2023-04-13 11:51:03 +08:00
{
IsSuper = true
};
lstUsers.Add(admin);
var readOnly = new AccountEx("-2", "Read-Only", "read-only", "", "", "", new List<string> { "-1" })
{
IsSuper = true
};
lstUsers.Add(readOnly);
_accountList = lstUsers;
2023-04-13 11:51:03 +08:00
}
/// <summary>
/// 更新指定的角色。
/// </summary>
/// <param name="newRole"></param>
/// <returns></returns>
public bool UpdateRole(Role newRole)
2023-04-13 11:51:03 +08:00
{
var oldRole = _roleList.Find((Role item) => item.RoleId == newRole.RoleId);
if (oldRole == null)
_roleList.Add(newRole);
2023-04-13 11:51:03 +08:00
else
_roleList[_roleList.IndexOf(oldRole)] = newRole;
var doc = XmlDoc;
var roleToUpdate = doc.Descendants("roleItem").FirstOrDefault(x => x.Attribute("id").Value == newRole.RoleId);
if (roleToUpdate != null)
2023-04-13 11:51:03 +08:00
{
// 修改现有的Role
roleToUpdate.RemoveNodes();
2023-04-13 11:51:03 +08:00
}
else
{
// 新增Role
roleToUpdate = new XElement("roleItem");
doc.Root.Element("roles").Add(roleToUpdate);
2023-04-13 11:51:03 +08:00
}
// 设置属性
roleToUpdate.SetAttributeValue("id", newRole.RoleId);
roleToUpdate.SetAttributeValue("name", newRole.RoleName);
roleToUpdate.SetAttributeValue("autologout", (newRole.IsAutoLogout ? "1" : "0"));
roleToUpdate.SetAttributeValue("logouttime", newRole.LogoutTime.ToString());
roleToUpdate.SetAttributeValue("buildin", newRole.IsBuildIn.ToString());
roleToUpdate.SetAttributeValue("description", newRole.Description);
// 创建权限清单
var permList = new XElement(NODE_NAME_PERMS_GROUP);
foreach (var perm in newRole.PermissionControlItems)
permList.Add(new XElement(NODE_NAME_PERMS_ITEM,
new XAttribute("name", perm.Key),
new XAttribute("value", (int)perm.Value)));
roleToUpdate.Add(permList);
doc.Save(FileName);
2023-04-13 11:51:03 +08:00
return true;
}
public bool DeleteRole(string roleId)
2023-04-13 11:51:03 +08:00
{
Load();
var roleToDelete = _roleList.Find((Role item) => item.RoleId == roleId);
if (roleToDelete != null)
2023-04-13 11:51:03 +08:00
{
_roleList.Remove(roleToDelete);
var xmlDoc = XmlDoc;
var list = (from m_xRole in xmlDoc.Descendants("roleItem")
where m_xRole.Attribute("id").Value == roleId
2023-04-13 11:51:03 +08:00
select m_xRole).ToList();
if (list.Count > 0)
{
list[0].Remove();
foreach (var item in _accountList)
2023-04-13 11:51:03 +08:00
{
if (item.RoleIDs.Contains(roleToDelete.RoleId))
2023-04-13 11:51:03 +08:00
{
item.RoleIDs.Remove(roleToDelete.RoleId);
2023-04-13 11:51:03 +08:00
}
}
list = (from m_xRole in xmlDoc.Descendants("role")
where m_xRole.Attribute("id").Value == roleToDelete.RoleId
2023-04-13 11:51:03 +08:00
select m_xRole).ToList();
if (list.Count > 0)
{
list.Remove();
}
xmlDoc.Save(FileName);
2023-04-13 11:51:03 +08:00
return true;
}
return false;
}
return false;
}
private Dictionary<string, MenuPermissionEnum> GetRolePermission(string roleId)
2023-04-13 11:51:03 +08:00
{
var perms = _roleList.FirstOrDefault(x => x.RoleId == roleId)?.PermissionControlItems;
if(perms == null)
LOG.Error($"Unable to find the Role by ID {roleId}, or the permission list is empty.");
return perms;
2023-04-13 11:51:03 +08:00
}
2023-09-05 10:20:23 +08:00
public List<AppMenu> GetMenusByRole(string roleId)
2023-04-13 11:51:03 +08:00
{
var list = new List<AppMenu>();
var rolePermission = GetRolePermission(roleId);
if (rolePermission == null)
return null;
foreach (var menu in GetAllMenus())
2023-04-13 11:51:03 +08:00
{
var appMenusHasPerm = new List<AppMenu>();
foreach (var menuItem in menu.MenuItems)
2023-04-13 11:51:03 +08:00
{
if (!rolePermission.TryGetValue(menuItem.MenuID, out var perm))
{
// 当前菜单的权限未定义
LOG.Error($"The permission of {menuItem.MenuID} is not defined.");
continue;
}
var appMenu = new AppMenu(menuItem.MenuID, menuItem.ViewModel, menuItem.ResKey, null,
menuItem.Description)
{
System = menuItem.System,
AlarmModule = menuItem.AlarmModule,
Permission = (int)perm
};
if (appMenu.Permission > (int)MenuPermissionEnum.MP_NONE)
2023-04-13 11:51:03 +08:00
{
appMenusHasPerm.Add(appMenu);
2023-04-13 11:51:03 +08:00
}
}
if (appMenusHasPerm.Count > 0)
2023-04-13 11:51:03 +08:00
{
var appMenu2 = new AppMenu(menu.MenuID, menu.ViewModel, menu.ResKey, appMenusHasPerm, menu.Description);
appMenu2.System = menu.System;
appMenu2.AlarmModule = menu.AlarmModule;
2023-04-13 11:51:03 +08:00
list.Add(appMenu2);
}
}
2023-04-13 11:51:03 +08:00
return list;
}
public int GetMenuPermission(string roleId, string menuName)
2023-04-13 11:51:03 +08:00
{
var rolePermission = GetRolePermission(roleId);
if (rolePermission.TryGetValue(menuName, out var perm))
return (int)perm;
return (int)MenuPermissionEnum.MP_NONE;
2023-04-13 11:51:03 +08:00
}
public bool UpdateAccount(AccountEx p_newAccount)
{
var accountEx = _accountList.Find((AccountEx item) => item.UserId == p_newAccount.UserId);
2023-04-13 11:51:03 +08:00
if (accountEx == null)
{
_accountList.Add(p_newAccount);
2023-04-13 11:51:03 +08:00
}
else
{
_accountList[_accountList.IndexOf(accountEx)] = p_newAccount;
2023-04-13 11:51:03 +08:00
}
var xdoc = XmlDoc;
var list = (from xAccount in xdoc.Descendants("userItem")
where xAccount.Attribute("id").Value == p_newAccount.UserId
2023-04-13 11:51:03 +08:00
select xAccount).ToList();
if (list.Count > 0)
{
list[0].SetAttributeValue("loginname", p_newAccount.LoginName);
list[0].SetAttributeValue("password", Encrypt(p_newAccount.Password));
list[0].SetAttributeValue("firstname", p_newAccount.FirstName);
list[0].SetAttributeValue("lastname", p_newAccount.LastName);
list[0].SetAttributeValue("email", p_newAccount.Email);
list[0].SetAttributeValue("description", p_newAccount.Description);
list[0].Element("rolegroup").RemoveAll();
foreach (var roleID in p_newAccount.RoleIDs)
2023-04-13 11:51:03 +08:00
{
list[0].Element("rolegroup").Add(new XElement("role", new XAttribute("id", roleID)));
}
}
else
{
var xElement = new XElement("userItem", new XAttribute("id", p_newAccount.UserId), new XAttribute("loginname", p_newAccount.LoginName), new XAttribute("password", Encrypt(p_newAccount.Password)), new XAttribute("firstname", p_newAccount.FirstName), new XAttribute("lastname", p_newAccount.LastName), new XAttribute("email", p_newAccount.Email), new XAttribute("description", p_newAccount.Description), new XElement("rolegroup"));
foreach (var roleID2 in p_newAccount.RoleIDs)
2023-04-13 11:51:03 +08:00
{
xElement.Element("rolegroup").Add(new XElement("role", new XAttribute("id", roleID2)));
}
xdoc.Root.Element("users").Add(xElement);
}
xdoc.Save(FileName);
2023-04-13 11:51:03 +08:00
return true;
}
public bool DeleteAccount(string p_strUserID)
{
var accountEx = _accountList.Find((AccountEx item) => item.UserId == p_strUserID);
2023-04-13 11:51:03 +08:00
if (accountEx != null)
{
_accountList.Remove(accountEx);
var xdoc = XmlDoc;
var list = (from xAccount in xdoc.Descendants("userItem")
2023-04-13 11:51:03 +08:00
where xAccount.Attribute("id").Value == p_strUserID
select xAccount).ToList();
if (list.Count > 0)
{
list[0].Remove();
xdoc.Save(FileName);
2023-04-13 11:51:03 +08:00
return true;
}
return false;
}
return false;
}
public string Encrypt(string encrytStr)
{
if (string.IsNullOrWhiteSpace(encrytStr))
{
return string.Empty;
}
try
{
var bytes = Encoding.UTF8.GetBytes(encrytStr);
2023-04-13 11:51:03 +08:00
return Convert.ToBase64String(bytes);
}
catch
{
return encrytStr;
}
}
public string Decrypt(string decryptStr)
{
if (string.IsNullOrWhiteSpace(decryptStr))
{
return string.Empty;
}
try
{
var bytes = Convert.FromBase64String(decryptStr);
2023-04-13 11:51:03 +08:00
return Encoding.UTF8.GetString(bytes);
}
catch
{
return decryptStr;
}
}
#endregion
2023-04-13 11:51:03 +08:00
}
}