From 1d3d35d1066c519084f311f7dc9da0a0953d4c12 Mon Sep 17 00:00:00 2001 From: kotcheshir73 Date: Fri, 18 Mar 2022 13:27:14 +0400 Subject: [PATCH] =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D0=BA=D0=B0=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20=D0=BC?= =?UTF-8?q?=D0=B0=D0=BF=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CoreModels/ModelsSecurity/IAccessModel.cs | 3 + .../ModelsSecurity/IEnviromentSettingModel.cs | 3 + .../CoreModels/ModelsSecurity/IUserModel.cs | 4 + .../ModelsSecurity/IUserRoleModel.cs | 2 + .../Attributes/CheckRigthForMapAttribute.cs | 12 + .../ModuleTools/BusinessLogics/Mapper.cs | 321 +++++++++--------- .../ViewModels/AccessViewModels.cs | 3 - .../ViewModels/EnviromentSettingViewModels.cs | 11 +- .../ViewModels/UserRoleViewModels.cs | 2 - .../ViewModels/UserViewModels.cs | 4 - 10 files changed, 197 insertions(+), 168 deletions(-) create mode 100644 DepartmentPortal/Common/ModuleTools/Attributes/CheckRigthForMapAttribute.cs diff --git a/DepartmentPortal/Common/CoreModels/ModelsSecurity/IAccessModel.cs b/DepartmentPortal/Common/CoreModels/ModelsSecurity/IAccessModel.cs index 920cd4c..b5dc78a 100644 --- a/DepartmentPortal/Common/CoreModels/ModelsSecurity/IAccessModel.cs +++ b/DepartmentPortal/Common/CoreModels/ModelsSecurity/IAccessModel.cs @@ -12,16 +12,19 @@ namespace CoreModels.ModelsSecurity /// /// Илентификатор роли /// + [CheckRigthForMap] Guid RoleId { get; } /// /// Тип операции /// + [CheckRigthForMap] AccessOperation AccessOperation { get; } /// /// Режим доступа /// + [CheckRigthForMap] AccessType AccessType { get; } } } \ No newline at end of file diff --git a/DepartmentPortal/Common/CoreModels/ModelsSecurity/IEnviromentSettingModel.cs b/DepartmentPortal/Common/CoreModels/ModelsSecurity/IEnviromentSettingModel.cs index c50de10..72b005f 100644 --- a/DepartmentPortal/Common/CoreModels/ModelsSecurity/IEnviromentSettingModel.cs +++ b/DepartmentPortal/Common/CoreModels/ModelsSecurity/IEnviromentSettingModel.cs @@ -12,16 +12,19 @@ namespace CoreModels.ModelsSecurity /// /// Ключ настройки /// + [CheckRigthForMap] string Key { get; } /// /// Значение настройки /// + [CheckRigthForMap] string Value { get; } /// /// Описание настройки /// + [CheckRigthForMap] string Description { get; } } } \ No newline at end of file diff --git a/DepartmentPortal/Common/CoreModels/ModelsSecurity/IUserModel.cs b/DepartmentPortal/Common/CoreModels/ModelsSecurity/IUserModel.cs index 97e92a7..bffe71d 100644 --- a/DepartmentPortal/Common/CoreModels/ModelsSecurity/IUserModel.cs +++ b/DepartmentPortal/Common/CoreModels/ModelsSecurity/IUserModel.cs @@ -12,16 +12,20 @@ namespace CoreModels.ModelsSecurity { string UserName { get; } + [CheckRigthForMap] string PasswordHash { get; } byte[] Avatar { get; } DateTime? DateLastVisit { get; } + [CheckRigthForMap] bool IsBanned { get; } + [CheckRigthForMap] DateTime? DateBanned { get; } + [CheckRigthForMap] int CountAttempt { get; } } } \ No newline at end of file diff --git a/DepartmentPortal/Common/CoreModels/ModelsSecurity/IUserRoleModel.cs b/DepartmentPortal/Common/CoreModels/ModelsSecurity/IUserRoleModel.cs index 21d0f4f..d972e42 100644 --- a/DepartmentPortal/Common/CoreModels/ModelsSecurity/IUserRoleModel.cs +++ b/DepartmentPortal/Common/CoreModels/ModelsSecurity/IUserRoleModel.cs @@ -12,8 +12,10 @@ namespace CoreModels.ModelsSecurity [EntityDependency("User", "UserId", "К какой роли относится пользователь")] public interface IUserRoleModel : IId { + [CheckRigthForMap] Guid RoleId { get; } + [CheckRigthForMap] Guid UserId { get; } } } \ No newline at end of file diff --git a/DepartmentPortal/Common/ModuleTools/Attributes/CheckRigthForMapAttribute.cs b/DepartmentPortal/Common/ModuleTools/Attributes/CheckRigthForMapAttribute.cs new file mode 100644 index 0000000..e0817fd --- /dev/null +++ b/DepartmentPortal/Common/ModuleTools/Attributes/CheckRigthForMapAttribute.cs @@ -0,0 +1,12 @@ +using System; + +namespace ModuleTools.Attributes +{ + /// + /// Признак, гооврящий о том, что нужна проверка доступа к значению свойства при создании одного объекта на основе другого + /// + [AttributeUsage(AttributeTargets.Property)] + public class CheckRigthForMapAttribute : Attribute + { + } +} \ No newline at end of file diff --git a/DepartmentPortal/Common/ModuleTools/BusinessLogics/Mapper.cs b/DepartmentPortal/Common/ModuleTools/BusinessLogics/Mapper.cs index 6406cc5..66f6886 100644 --- a/DepartmentPortal/Common/ModuleTools/BusinessLogics/Mapper.cs +++ b/DepartmentPortal/Common/ModuleTools/BusinessLogics/Mapper.cs @@ -1,165 +1,182 @@ using ModuleTools.Attributes; using System; using System.Collections; +using System.Linq; using System.Reflection; namespace ModuleTools.BusinessLogics { - /// - /// Маппер сущностей - /// - public class Mapper - { - /// - /// Преобразование из одного класса в другой - /// - /// - /// - /// - /// - /// - public static To MapToClass(From obj, bool haveRigth) where To : class => FillObject(obj, (To)Activator.CreateInstance(typeof(To)), haveRigth); + /// + /// Маппер сущностей + /// + public class Mapper + { + /// + /// Преобразование из одного класса в другой + /// + /// + /// + /// + /// + /// + public static To MapToClass(From obj, bool haveRigth) where To : class => FillObject(obj, (To)Activator.CreateInstance(typeof(To)), haveRigth); - /// - /// Преобразование из одного класса в другой - /// - /// - /// - /// - /// - /// - public static To MapToClass(From obj, To newObject, bool haveRigth) where To : class => FillObject(obj, newObject, haveRigth); + /// + /// Преобразование из одного класса в другой + /// + /// + /// + /// + /// + /// + public static To MapToClass(From obj, To newObject, bool haveRigth) where To : class => FillObject(obj, newObject, haveRigth); - /// - /// Заполнение объекта - /// - /// - /// - /// - /// - /// - /// - private static To FillObject(From obj, To newObject, bool haveRigth) - where To : class - { - if (obj == null) - { - return null; - } + /// + /// Заполнение объекта + /// + /// + /// + /// + /// + /// + /// + private static To FillObject(From obj, To newObject, bool haveRigth) + where To : class + { + if (obj == null) + { + return null; + } - if (newObject == null) - { - return null; - } - var typeFrom = typeof(From); - var typeTo = typeof(To); - var properties = typeTo.GetProperties(); - foreach (var property in properties) - { - object value = obj; - var customAttribute = property.GetCustomAttribute(); - if (customAttribute != null) - { - if (customAttribute.IsDifficle) - { - var props = customAttribute.PropertyNameFromModel.Split('.'); - foreach (var prop in props) - { - if (prop == "ToString") - { - value = value.ToString(); - break; - } - else if (prop == "Count") - { - value = (value as ICollection)?.Count; - break; - } - else if (prop == "Method") - { - int index = 0; - while (true) - { - if (props[index++] == "Method") - break; - if (index == props.Length) - { - break; - } - } - var methodName = props[index].Split('[')?[0]; - if (string.IsNullOrEmpty(methodName)) - { - break; - } - var parameters = props[index].Split(new char[] { '[' , ']'}, StringSplitOptions.RemoveEmptyEntries)?[1].Split(','); - var objs = new object[parameters.Length]; - for(int i = 0; i < parameters.Length; ++i) - { - var type = parameters[i].Split(':')[0]; - switch(type) - { - case "Enum": - objs[i] = (int)Enum.Parse(customAttribute.MethodParams[i], parameters[i].Split(':')[1]); - break; - } - } - value = typeFrom.InvokeMember(methodName, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, value, objs); - break; - - } - var bindingProperty = value.GetType().GetProperty(prop); - if (bindingProperty != null) - { - value = bindingProperty.GetValue(value); - if (value is null) - { - break; - } - } - else - { - value = null; - break; - } - } - } - else - { - if (customAttribute.PropertyNameFromModel == "ToString") - { - value = value.ToString(); - } - var bindingProperty = typeFrom.GetProperty(customAttribute.PropertyNameFromModel); - if (bindingProperty != null) - { - value = bindingProperty.GetValue(obj); - } - } - if ((haveRigth && !customAttribute.AllowCopyWithoutRigth) || customAttribute.AllowCopyWithoutRigth) - { - if (property.PropertyType.Name.StartsWith("Nullable")) - { - if (Nullable.GetUnderlyingType(property.PropertyType).IsEnum) - { - property.SetValue(newObject, Enum.Parse(Nullable.GetUnderlyingType(property.PropertyType), value.ToString())); - continue; - } - } - property.SetValue(newObject, value); - } - } - else + if (newObject == null) + { + return null; + } + var typeFrom = typeof(From); + var typeTo = typeof(To); + var properties = typeTo.GetProperties().Where(x => x.CanWrite); + foreach (var property in properties) + { + var checkRight = property.GetCustomAttribute(); + if (!haveRigth && checkRight != null) { - var bindingProperty = value.GetType().GetProperty(property.Name); - if (bindingProperty != null) - { - property.SetValue(newObject, bindingProperty.GetValue(value)); - } - } - } + continue; + } - return newObject; - } - } + object value = obj; + var customAttribute = property.GetCustomAttribute(); + if (customAttribute != null) + { + if (!haveRigth && !customAttribute.AllowCopyWithoutRigth) + { + continue; + } + value = GetValueFromCustomAttribute(customAttribute, typeFrom, obj); + } + else + { + var bindingProperty = value.GetType().GetProperty(property.Name); + if (bindingProperty != null) + { + value = bindingProperty.GetValue(obj); + } + } + if (value is null) + { + continue; + } + + if (property.PropertyType.Name.StartsWith("Nullable") && Nullable.GetUnderlyingType(property.PropertyType).IsEnum) + { + property.SetValue(newObject, Enum.Parse(Nullable.GetUnderlyingType(property.PropertyType), value.ToString())); + continue; + } + property.SetValue(newObject, value); + } + + return newObject; + } + + private static object GetValueFromCustomAttribute(MapConfigurationAttribute customAttribute, Type typeFrom, object obj) + { + object value = obj; + if (customAttribute.IsDifficle) + { + var props = customAttribute.PropertyNameFromModel.Split('.'); + foreach (var prop in props) + { + if (prop == "ToString") + { + value = value.ToString(); + break; + } + else if (prop == "Count") + { + value = (value as ICollection)?.Count; + break; + } + else if (prop == "Method") + { + int index = 0; + while (true) + { + if (props[index++] == "Method") + break; + if (index == props.Length) + { + break; + } + } + var methodName = props[index].Split('[')?[0]; + if (string.IsNullOrEmpty(methodName)) + { + break; + } + var parameters = props[index].Split(new char[] { '[', ']' }, StringSplitOptions.RemoveEmptyEntries)?[1].Split(','); + var objs = new object[parameters.Length]; + for (int i = 0; i < parameters.Length; ++i) + { + var type = parameters[i].Split(':')[0]; + switch (type) + { + case "Enum": + objs[i] = (int)Enum.Parse(customAttribute.MethodParams[i], parameters[i].Split(':')[1]); + break; + } + } + value = typeFrom.InvokeMember(methodName, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, value, objs); + break; + + } + var bindingProperty = value.GetType().GetProperty(prop); + if (bindingProperty != null) + { + value = bindingProperty.GetValue(value); + if (value is null) + { + break; + } + } + else + { + value = null; + break; + } + } + } + else + { + if (customAttribute.PropertyNameFromModel == "ToString") + { + value = value.ToString(); + } + var bindingProperty = typeFrom.GetProperty(customAttribute.PropertyNameFromModel); + if (bindingProperty != null) + { + value = bindingProperty.GetValue(obj); + } + } + return value; + } + } } \ No newline at end of file diff --git a/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/AccessViewModels.cs b/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/AccessViewModels.cs index a9c9628..117a830 100644 --- a/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/AccessViewModels.cs +++ b/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/AccessViewModels.cs @@ -18,7 +18,6 @@ namespace SecurityBusinessLogic.ViewModels public class AccessViewModel : ElementViewModel, IAccessModel { [ViewModelControlElementProperty("Роль", ControlType.ControlGuid, MustHaveValue = true, ReadOnly = true, ControlTypeObject = "SecurityWindowsDesktop.EntityControls.ControlRoleList, SecurityWindowsDesktop")] - [MapConfiguration("RoleId", AllowCopyWithoutRigth = false)] public Guid RoleId { get; set; } [ViewModelControlListProperty("Роль", ColumnWidth = 100)] @@ -26,14 +25,12 @@ namespace SecurityBusinessLogic.ViewModels public string RoleName { get; set; } [ViewModelControlElementProperty("Операция", ControlType.ControlEnum, MustHaveValue = true)] - [MapConfiguration("AccessOperation", AllowCopyWithoutRigth = false)] public AccessOperation AccessOperation { get; set; } [ViewModelControlListProperty("Операция")] public string AccessOperationTitle => AccessOperation.ToString("G"); [ViewModelControlElementProperty("Тип", ControlType.ControlEnum, MustHaveValue = true)] - [MapConfiguration("AccessType", AllowCopyWithoutRigth = false)] public AccessType AccessType { get; set; } [ViewModelControlListProperty("Тип", ColumnWidth = 150)] diff --git a/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/EnviromentSettingViewModels.cs b/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/EnviromentSettingViewModels.cs index c0d88a2..ed7d14c 100644 --- a/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/EnviromentSettingViewModels.cs +++ b/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/EnviromentSettingViewModels.cs @@ -5,10 +5,10 @@ using ModuleTools.ViewModels; namespace SecurityBusinessLogic.ViewModels { - /// - /// Список общих настроек системы - /// - public class EnviromentSettingListViewModel : ListViewModel { } + /// + /// Список общих настроек системы + /// + public class EnviromentSettingListViewModel : ListViewModel { } /// /// Элемент общих настроек системы @@ -18,17 +18,14 @@ namespace SecurityBusinessLogic.ViewModels { [ViewModelControlListProperty("Ключ")] [ViewModelControlElementProperty("Ключ", ControlType.ControlString, MustHaveValue = true, ReadOnly = true)] - [MapConfiguration("Key", AllowCopyWithoutRigth = false)] public string Key { get; set; } [ViewModelControlListProperty("Значение")] [ViewModelControlElementProperty("Значение", ControlType.ControlString, MustHaveValue = true)] - [MapConfiguration("Value", AllowCopyWithoutRigth = false)] public string Value { get; set; } [ViewModelControlListProperty("Описание")] [ViewModelControlElementProperty("Описание", ControlType.ControlText, Height = 200)] - [MapConfiguration("Description", AllowCopyWithoutRigth = false)] public string Description { get; set; } } } \ No newline at end of file diff --git a/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/UserRoleViewModels.cs b/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/UserRoleViewModels.cs index 046f905..3454938 100644 --- a/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/UserRoleViewModels.cs +++ b/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/UserRoleViewModels.cs @@ -18,7 +18,6 @@ namespace SecurityBusinessLogic.ViewModels public class UserRoleViewModel : ElementViewModel, IUserRoleModel { [ViewModelControlElementProperty("Пользователь", ControlType.ControlGuid, MustHaveValue = true, ReadOnly = false, ControlTypeObject = "SecurityWindowsDesktop.EntityControls.ControlUserList, SecurityWindowsDesktop")] - [MapConfiguration("UserId", AllowCopyWithoutRigth = false)] public Guid UserId { get; set; } [ViewModelControlListProperty("Пользователь")] @@ -26,7 +25,6 @@ namespace SecurityBusinessLogic.ViewModels public string UserName { get; set; } [ViewModelControlElementProperty("Роль", ControlType.ControlGuid, MustHaveValue = true, ReadOnly = false, ControlTypeObject = "SecurityWindowsDesktop.EntityControls.ControlRoleList, SecurityWindowsDesktop")] - [MapConfiguration("RoleId", AllowCopyWithoutRigth = false)] public Guid RoleId { get; set; } [ViewModelControlListProperty("Роль")] diff --git a/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/UserViewModels.cs b/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/UserViewModels.cs index b698695..f8c203d 100644 --- a/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/UserViewModels.cs +++ b/DepartmentPortal/Security/SecurityBusinessLogic/ViewModels/UserViewModels.cs @@ -23,7 +23,6 @@ namespace SecurityBusinessLogic.ViewModels [ViewModelControlElementProperty("Логин", ControlType.ControlString, MustHaveValue = true)] public string UserName { get; set; } - [MapConfiguration("PasswordHash", AllowCopyWithoutRigth = false)] public string PasswordHash { get; set; } [ViewModelControlElementProperty("Фото", ControlType.ControlImage, Width = 200, Height = 200)] @@ -33,21 +32,18 @@ namespace SecurityBusinessLogic.ViewModels public DateTime? DateLastVisit { get; set; } [ViewModelControlElementProperty("Заблокирован", ControlType.ControlBool, MustHaveValue = true)] - [MapConfiguration("IsBanned", AllowCopyWithoutRigth = false)] public bool IsBanned { get; set; } [ViewModelControlListProperty("Блокир.", ColumnWidth = 80)] public string Banned => IsBanned ? "Да" : "Нет"; [ViewModelControlElementProperty("Дата блокировки", ControlType.ControlDateTime, ReadOnly = true)] - [MapConfiguration("DateBanned", AllowCopyWithoutRigth = false)] public DateTime? DateBanned { get; set; } [ViewModelControlListProperty("Дата Б.", ColumnWidth = 100)] public string DateBannedTitle => DateBanned.HasValue ? DateBanned.Value.ToShortDateString() : string.Empty; [ViewModelControlElementProperty("Попытки входа", ControlType.ControlInt, ReadOnly = true)] - [MapConfiguration("CountAttempt", AllowCopyWithoutRigth = false)] public int CountAttempt { get; set; } } } \ No newline at end of file